bzoj 2120 数颜色(带修改莫队模板题)

题目:1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。 2、 R P Col 把第P支画笔替换为颜色Col。

思路:带修改莫队,不修改时直接对区间维护就行,带修改时多维护一个时间变量,与不修改的莫队同样的思路。

#include<bits/stdc++.h>
using namespace std;
const int maxn=10005;
struct node1{
    int l,r,id,t;
    node1(){}
    node1(int _l,int _r,int _id,int _t)
    {
        l=_l; r=_r; id=_id; t=_t;
    }
}s[maxn];
int block[maxn];
bool cmp1(const node1 &a,const node1 &b)
{
    if(block[a.l]==block[b.l])
    {
        if(a.r==b.r) return a.t<b.t;
        return a.r<b.r;
    }
    return a.l<b.l;
}
struct node2{
    int pos,la,now;
    node2(){}
    node2(int _pos,int _la,int _now)
    {
        pos=_pos; la=_la; now=_now;
    }
}u[maxn];
int la[maxn];
int a[maxn],n,m,m1,m2;

int ans[maxn],c[1000010],sum,l,r,t;
void update1(int k,int v)
{
    if(k>=l&&k<=r)
    {
        c[a[k]]--;
        if(c[a[k]]==0) sum--;
        a[k]=v;
        c[a[k]]++;
        if(c[a[k]]==1) sum++;
    }
    else
        a[k]=v;
}
void update2(int k,int v)
{
    if(c[a[k]]) sum--;
    c[a[k]]+=v;
    if(c[a[k]]) sum++;
}
void Modui()
{
    l=1,r=0;t=0;sum=0;
    for(int i=1;i<=m1;i++)
    {
        while(t<s[i].t)
        {
            t++;
            update1(u[t].pos,u[t].now);
        }
        while(t>s[i].t)
        {
            update1(u[t].pos,u[t].la);
            t--;
        }

        while(r<s[i].r)
        {
            r++;
            update2(r,1);
        }
        while(r>s[i].r)
        {
            update2(r,-1);
            r--;
        }
        while(l<s[i].l)
        {
            update2(l,-1);
            l++;
        }
        while(l>s[i].l)
        {
            l--;
            update2(l,1);
        }
        ans[s[i].id]=sum;
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        la[i]=a[i];
    }
    m1=m2=0;
    for(int i=1;i<=m;i++)
    {
        char ch[3];
        int x,y;
        scanf("%s%d%d",ch,&x,&y);
        if(ch[0]=='Q')
        {
            m1++;
            s[m1]=node1(x,y,m1,m2);
        }
        else
        {
            u[++m2]=node2(x,la[x],y);
            la[x]=y;
        }
    }
    int o=sqrt(n);
    for(int i=1;i<=n;i++)
        block[i]=i/o;
    sort(s+1,s+m1+1,cmp1);
    Modui();
    for(int i=1;i<=m1;i++)
        printf("%d\n",ans[i]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/dllpXFire/article/details/82319411