BZOJ2120: 数颜色

【传送门:BZOJ2120


简要题意:

  有n个数,有m种操作:

  1.Q l r求出l到r中共有多少种不同的数

  2.R x c将第x个数改为c


题解:

  带修莫队例题

  具体请膜大米饼


参考代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
struct node
{
    int l,r,t,ans;
    int id;
}a[11000];int lenx;
struct ch
{
    int x,c,last;
}b[11000];int leny;
int block;
int n,m,ans;
char s[10];
int col[11000],pos[11000];
int last[11000];
bool cmpx(node n1,node n2)
{
    if(pos[n1.l]>pos[n2.l])return false;
    else if(pos[n1.l]<pos[n2.l])return true;
    else if(pos[n1.r]>pos[n2.r])return false;
    else if(pos[n1.r]<pos[n2.r])return true;
    else return n1.t<n2.t;
}
int sum[1100000];
void change2(int x,int c)
{
    int tmp=sum[col[x]];
    sum[col[x]]+=c;
    if(tmp==0&&sum[col[x]]==1)ans++;
    else if(tmp==1&&sum[col[x]]==0)ans--;
}
int l,r,t;
void change1(int x,int c)
{
    if(l<=x&&x<=r)
    {
        sum[col[x]]--;if(sum[col[x]]==0)ans--;
        col[x]=c;
        sum[col[x]]++;if(sum[col[x]]==1)ans++;
    }
    else col[x]=c;
}
bool cmpy(node n1,node n2)
{
    return n1.id<n2.id;
}
int main()
{
    lenx=leny=0;
    scanf("%d%d",&n,&m);
    block=sqrt(n);
    memset(last,0,sizeof(last));
    for(int i=1;i<=n;i++){scanf("%d",&col[i]);last[i]=col[i];}
    for(int i=1;i<=n;i++) pos[i]=(i-1)/block+1;
    for(int i=1;i<=m;i++)
    {
        scanf("%s",s+1);
        if(s[1]=='Q')
        {
            int x,y;
            scanf("%d%d",&x,&y);
            a[++lenx].l=x;a[lenx].r=y;a[lenx].t=leny;
            a[lenx].id=i;
        }
        else
        {
            int x,y;
            scanf("%d%d",&x,&y);
            b[++leny].x=x;b[leny].c=y;
            b[leny].last=last[x];
            last[x]=y;
        }
    }
    sort(a+1,a+1+lenx,cmpx);
    l=1,r=0,t=0;ans=0;
    for(int i=1;i<=lenx;i++)
    {
        while(t>a[i].t) change1(b[t].x,b[t].last),t--;
        while(t<a[i].t) t++,change1(b[t].x,b[t].c);
        while(r<a[i].r) r++,change2(r,1);
        while(l>a[i].l) l--,change2(l,1);
        while(r>a[i].r) change2(r,-1),r--;
        while(l<a[i].l) change2(l,-1),l++;
        a[i].ans=ans;
    }
    sort(a+1,a+1+lenx,cmpy);
    for(int i=1;i<=lenx;i++)printf("%d\n",a[i].ans);
    return 0;
}

 

posted @ 2018-03-14 20:37  Star_Feel  阅读(227)  评论(0编辑  收藏  举报