BZOJ 1878 HH的项链

Posted on 2016-09-15 21:03  ziliuziliu  阅读(119)  评论(0编辑  收藏  举报

不能分块(显然复杂度会炸啊。。。。。)

离线+BIT。每个颜色在每个询问中只出现一次。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 50050
#define maxm 200050
#define maxc 1000500
using namespace std;
int n,a[maxn],aft[maxn],pre[maxn],regis[maxc],ans[maxm],m,p=1,t[maxn];
struct query
{
    int l,r,id;
}q[maxm];
bool cmp(query x,query y)
{
    if (x.l==y.l) return x.r<y.r;
    return x.l<y.l;
}
int lowbit(int x)
{
    return (x&(-x));
}
void add(int x,int val)
{
    for (int i=x;i<=n;i+=lowbit(i))
        t[i]+=val;
}
int ask(int x)
{
    int ret=0;
    for (int i=x;i>=1;i-=lowbit(i))
        ret+=t[i];
    return ret;
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        pre[i]=regis[a[i]];aft[pre[i]]=i;
        regis[a[i]]=i;
    }    
    scanf("%d",&m);
    for (int i=1;i<=m;i++)
    {
        scanf("%d%d",&q[i].l,&q[i].r);
        q[i].id=i;
    }
    for (int i=1;i<=n;i++)
    {
        if (!pre[i]) add(i,1);
        if (!aft[i]) aft[i]=n+1;
    }
    sort(q+1,q+m+1,cmp);
    for (int i=1;i<=m;i++)
    {
        for (int j=p;j<=q[i].l-1;j++)
        {
            add(j,-1);add(aft[j],1);
        }
        p=q[i].l;
        ans[q[i].id]=ask(q[i].r)-ask(q[i].l-1);
    }
    for (int i=1;i<=m;i++)
        printf("%d\n",ans[i]);
    return 0;
}