2

给定一个整数数组 A ,我试图找出在给定位置 j ,从 A 中的每个 i=0 到 i=j 发生了多少次 A[j]。我设计了如下所示的解决方案

map<int,int> CF[400005];
for(int i=0;i<n;++i)
{
   cin>>A[i];
   if(i!=0)
      CF[i-1] = CF[i];
   ++CF[i][A[i]]; 
}

比我可以在登录时间内回答每个查询。但是这个过程使用了太多的内存。有什么方法可以使用更少的内存吗?

如需更多说明,您可以查看我正在尝试解决的问题http://codeforces.com/contest/190/problem/D

4

2 回答 2

3

创建一个与 mapB大小相同的数组。对于每个in跟踪before的出现次数。跟踪给定元素的最后一次出现。然后你在恒定时间内回答查询,它只需要 O(n) 内存。ACjB[j]A[j]jC

对不起我的伪 C++。

map<int,int> C;
int B[n]; // zeros

for(int i=0;i<n;++i)
{
    cin >> A[i];
    int prev = C[A[i]]; // let me assume it gives -1 if no element

    if (pref == -1) // this is the fist occurrence of B[i]
        B[i] = 1;
    else // if not the first, then add previous occurrences
        B[i] = B[prev] + 1 

    C[A[i]] = i; // keep track where the last info about A[j] is
}
于 2014-01-14T10:22:33.827 回答
1

没有给这个太多时间,但也许不是使用地图来定位所有位置,而是使用一个列表,在其中为每个元素放置该元素计数发生变化的点,这就是:

struct count_info
{
    int index;
    int count;
    count_info* next;
};
...
std::map<int, count_info*> data;

,然后在该队列中查找正确的位置。您仍然需要一张地图,但是在下面您将只有这些指针的列表,并且在查询时您在地图中查找 A[i],然后在 i > index && next && i <下一个->索引。当然,如果 logn 是必须的,那么这将失败,因为列表查找最多为 n。

于 2014-01-14T10:09:20.700 回答