BZOJ2120: 数颜色

来源:互联网 发布:mysql两阶段提交 编辑:程序博客网 时间:2024/05/21 15:30

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
HINT

对于100%的数据,N≤10000,M≤10000,修改操作不多于1000次,所有的输入数据中出现的所有整数均大于等于1且不超过10^6。

题目传送门

我是班上前几个学莫队的,结果。。是倒数几个学带修莫队的。。
昨天晚上luogu有比赛,第二题带修莫队能水65分
于是怒而学习带修莫队

之前以为带修莫队是洪水猛兽,其实只改了那么一点点…
每次跳格子的时候先跳到第t次操作
排序时多一个关键字就差不多了

真的是好理解(也许我天生适合打暴力..)

再来一句经典台词

There are moments in all of our lives when we are compelled to ask ourselves, how far are we willing to go for what we want? How much are we willing to risk, tosacrifice, to endure? Because it’s one thing to yearn for something…But quite another to find the strength to achieve it.我们生命中有些时刻会让我们扪心自问:为了追寻你要的东西,你愿意付出多少?我们愿意冒多大的风险,去牺牲,去忍耐?因为渴望是一回事,而得到去实现的力量却是另一回事。                                       ——《Forever》

代码如下:

#include<cmath>#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>using namespace std;int n,m,Be[1100000],unit;struct node{    int l,r,t,id,s;}q[1100000];struct Gai{    int Pos,New,Old;}c[1100000];int s[1100000],l,r;int color[1100000],now[1100000];bool cmp(node a,node b){    return Be[a.l]==Be[b.l]?(Be[a.r]==Be[b.r]?a.t<b.t:a.r<b.r):a.l<b.l;}int T=0,R=0,nt;int ans;void change(int x,int d){    color[x]+=d;    if(d>0&&color[x]==1)ans++;    if(d<0&&color[x]==0)ans--;}void past(int x,int d){    if(l<=x&&x<=r)change(d,1),change(s[x],-1);    s[x]=d;}bool id(node a,node b){    return a.id<b.id;}int main(){    scanf("%d%d",&n,&m);unit=pow(n,0.666666);    for(int i=1;i<=n;i++){        scanf("%d",&s[i]);        Be[i]=i/unit+1;now[i]=s[i];    }    for(int i=1;i<=m;i++){        char st[3];int x,y;        scanf("%s%d%d",st+1,&x,&y);        if(st[1]=='Q')q[++R].l=x,q[R].r=y,q[R].t=T,q[R].id=R;        else c[++T].Pos=x,c[T].New=y,c[T].Old=now[x],now[x]=y;    }    sort(q+1,q+1+R,cmp);    l=1,r=0,nt=0;ans=0;    for(int i=1;i<=R;i++){        while(nt<q[i].t)past(c[nt+1].Pos,c[nt+1].New),nt++;        while(nt>q[i].t)past(c[nt].Pos,c[nt].Old),nt--;        while(l<q[i].l)change(s[l],-1),l++;        while(l>q[i].l)change(s[l-1],1),l--;        while(r<q[i].r)change(s[r+1],1),r++;        while(r>q[i].r)change(s[r],-1),r--;        q[i].s=ans;    }    sort(q+1,q+1+R,id);    for(int i=1;i<=R;i++)printf("%d\n",q[i].s);    return 0;}

by_lmy