首页 > 代码库 > BZOJ 1878 HH的项链

BZOJ 1878 HH的项链

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

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

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define maxn 50050#define maxm 200050#define maxc 1000500using 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;}

 

BZOJ 1878 HH的项链