查询区间内不同数字的个数 lydsy1878


描述 :
HH有一串由各种漂亮的贝壳组成的项链。HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH不断地收集新的贝壳,因此, 他的项链变得越来越长。有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同 的贝壳?这个问题很难回答。。。因为项链实在是太长了。于是,他只好求助睿智的你,来解 决这个问题。

Input


第一行:一个整数N,表示项链的长度。 第二行:N个整数,表示依次表示项链中贝壳的编号(编号为0到1000000之间的整数)。 第三行:一个整数M,表示HH询问的个数。 接下来M行:每行两个整数,L和R(1 ≤ L ≤ R ≤ N),表示询问的区间。 N<=50000 M<=200000

Output

M行,每行一个整数,依次表示询问对应的答案。

Sample Input

6

1 2 3 4 3 5

3

1 2 

3 5

2 6

Sample Output

2

2

4



以上转自(大视野测评)



算法很机智,实现也很容易。是离线查询的思想。预处理:先将N个数字读取进来,用next[]数组储存每个数字下一次出现的位置,fir[i]布尔数组表示从当前查询的位置到结尾第i个元素是否为第一次出现,那么区间[1,x]的fir[i]的和即为这个区间的数的个数,用一个树状数组即可。再将M次查询读取进来,按查询区间的左端点进行排序,然后开始,遍历M个查询的左端点,将区间以前出现过的数字用next[]数组转移至左端点以后,这样区间[左端点的坐标,x]的fir[i]的和即为这个区间的数的个数。再对这个区间进行查询。时间复杂度:预处理O(N + Mlog(M)) 查询O(Mlog(N)+N)



#include
#include
#include
#include


using namespace std;


int N,M;
const int SIZE = 50005;
int c[SIZE];
int A[SIZE];
int Next[SIZE];
int res[200005];
int show[1000005];
bool fir[SIZE];


struct Q
{
    int l,r;
    int pos;
}q[200005];


int lowbit(int k)
{
    return k&(-k);
}


void modify(int n,int v)
{
    while(n <= N)
    {
        c[n] += v;
        n += lowbit(n);
    }
}


int sum(int n)
{
    int ans = 0;
    while(n > 0)
    {
        ans += c[n];
        n -= lowbit(n);
    }
    return ans;
}


int cmp(Q a, Q b)
{
    return a.l < b.l;
}


int main()
{
    scanf("%d",&N);
    for(int i=1;i<=N;i++) scanf("%d",&A[i]);


    for(int i=N;i>=1;i--)
    {
        if(!show[A[i]])
        {
            show[A[i]] = i;
            fir[i] = true;
        }
        else
        {
            Next[i] = show[A[i]];
            fir[Next[i]] = false;
            fir[i] = true;
            show[A[i]] = i;
        }
    }


    scanf("%d",&M);
    for(int i=1;i<=M;i++)
    {
        scanf("%d%d",&q[i].l,&q[i].r);
        q[i].pos = i;
    }
    sort(q+1,q+1+M,cmp);


    for(int i=1;i<=N;i++)
        if(fir[i])
        {
            modify(i,1);
        }
    int qtemp = q[1].l;
    int ptr = 1;
    for(int i=1;i<=M;i++)
    {
        for(;ptr

你可能感兴趣的:(离线查询)