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

来源:互联网 发布:java证书有哪些 编辑:程序博客网 时间:2024/05/17 22:31

描述 :
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<cstdio>#include<cstring>#include<iostream>#include<algorithm>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<q[i].l;ptr++)        {            if(fir[ptr])            {                modify(ptr,-1);                fir[ptr] = false;                if(Next[ptr])                {                    fir[Next[ptr]] = true;                    modify(Next[ptr],1);                }            }        }        ptr = q[i].l;        qtemp = q[i].l;        res[q[i].pos] = sum(q[i].r) - sum(q[i].l-1);    }    for(int i=1;i<=M;i++) printf("%d\n",res[i]);    return 0;}

0 0