[BZOJ2120]数颜色(带修改莫队入门)

2120: 数颜色

Time Limit: 6 Sec   Memory Limit: 259 MB
Submit: 7512   Solved: 3053
[ Submit][ Status][ Discuss]

Description

墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会像你发布如下指令: 1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。 2、 R P Col 把第P支画笔替换为颜色Col。为了满足墨墨的要求,你知道你需要干什么了吗?

Input

第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数。第2行N个整数,分别代表初始画笔排中第i支画笔的颜色。第3行到第2+M行,每行分别代表墨墨会做的一件事情,格式见题干部分。

Output

对于每一个Query的询问,你需要在对应的行中给出一个数字,代表第L支画笔到第R支画笔中共有几种不同颜色的画笔。

Sample Input

6 5
1 2 3 4 5 5
Q 1 4
Q 2 6
R 1 2
Q 1 4
Q 2 6

Sample Output

4
4
3
4

思路&&分析

    待修改莫队入门题,具体实现思路不详细解释了(存个Code而已..)

Code

#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
bool Finish_read;
template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;}
template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+'0');}
template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');}
template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);}
/*================Header Template==============*/
const int maxn=10005;
int col[maxn],cnt[maxn*100],l,r,ans,cc,cq,n,qq,lst[maxn],blk,mov,res[maxn];
bool vis[maxn];
struct Change {
    int pre,nxt,pos;
}c[maxn];
struct Query {
    int t,l,r,x,id;
    inline bool operator < (const Query &rhs) const {
        return x==rhs.x?r<rhs.r:x<rhs.x;
    }
}q[maxn];
inline void modify(int x) {
    if(vis[x]) {
        if(!--cnt[col[x]])
            ans--;
    }
    else {
        if(!cnt[col[x]]++)
            ans++;
    }
    vis[x]^=1;
}
inline void solve(int pos,int c) {
    if(vis[pos]) {
        modify(pos);
        col[pos]=c;
        modify(pos);
    }
    else
        col[pos]=c;
}
int main() {
    read(n),read(qq);
    for(int i=1;i<=n;i++)
        read(col[i]),lst[i]=col[i];
    blk=sqrt(n)*16/7;
    for(int i=1;i<=qq;i++) {
        char op[2];
        scanf("%s",op);
        int l,r;
        read(l),read(r);
        if(op[0]=='Q')
            q[++cq].l=l,q[cq].r=r,q[cq].id=cq,q[cq].x=q[cq].l/blk,q[cq].t=cc;
        else
            c[++cc].pre=lst[l],c[cc].nxt=r,lst[l]=r,c[cc].pos=l;
    }
    sort(q+1,q+cq+1);
    l=r=ans=cnt[col[1]]=1,mov=0;
    vis[1]=1;
    for(int i=1;i<=cq;i++) {
//      cout<<q[i].l<<" "<<q[i].r<<" "<<q[i].id<<" "<<q[i].t<<" "<<q[i-1].t<<endl;
        for(int j=q[i-1].t+1;j<=q[i].t;j++)
            solve(c[j].pos,c[j].nxt);
        for(int j=q[i-1].t;j>q[i].t;j--)
            solve(c[j].pos,c[j].pre);
        while(l<q[i].l)
            modify(l++);
        while(l>q[i].l)
            modify(--l);
        while(r<q[i].r)
            modify(++r);
        while(r>q[i].r)
            modify(r--);
        res[q[i].id]=ans;
    }
    for(int i=1;i<=cq;i++)
        printf("%d\n",res[i]);
}

猜你喜欢

转载自blog.csdn.net/effervescence/article/details/79542357