BZOJ2120/洛谷P1903 [国家集训队] 数颜色 [带修改莫队]
数颜色
题目描述
墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会向你发布如下指令:
1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。
2、 R P Col 把第P支画笔替换为颜色Col。
为了满足墨墨的要求,你知道你需要干什么了吗?
输入输出格式
输入格式:
第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数。
第2行N个整数,分别代表初始画笔排中第i支画笔的颜色。
第3行到第2+M行,每行分别代表墨墨会做的一件事情,格式见题干部分。
输出格式:
对于每一个Query的询问,你需要在对应的行中给出一个数字,代表第L支画笔到第R支画笔中共有几种不同颜色的画笔。
输入输出样例
输入样例#1: 复制
6 5
1 2 3 4 5 5
Q 1 4
Q 2 6
R 1 2
Q 1 4
Q 2 6
输出样例#1: 复制
4
4
3
4
分析:
一开始不会打带修改莫队,就直接打了个不带分块的普通莫队,然后在洛谷水了40分,然后看了某位大佬的博客以后,会了带修改莫队,结果被洛谷数据卡常卡了一个小时,这数据也太可怕了吧。。。给出数据的人跪了Orz。。。(BZOJ上的数据一遍就过了。。。)把能用的优化都丢进去了,然后8000+ms过的。。。如果不会带修改莫队,请参考这位大佬的博客。这里蒟蒻就只放代码了。
Code:
#include<bits/stdc++.h> #define swap(x,y) x^=y,y^=x,x^=y using namespace std; const int N=5e4+7; const int M=1e6+7; int n,m,s,L,R,tot,ans[N]; int a[N],c[M],rn,qn; struct Node{ int x,y,id,pos; friend bool operator < (const Node a,const Node b){ if((a.x-1)/s!=(b.x-1)/s)return ((a.x-1)/s)<((b.x-1)/s); if((a.y-1)/s!=(b.y-1)/s)return ((a.y-1)/s)<((b.y-1)/s); return a.id<b.id; } }Q[N]; struct Num{ int x,y;}C[N]; char obuf[1<<24], *O=obuf; inline int read() { char ch=getchar();int num=0; while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9'){ num=num*10+ch-'0';ch=getchar();} return num; } inline void print(int x) { if(x>9)print(x/10); *O++ = x%10+'0'; } inline void change(int x,int i) { if(Q[i].x<=C[x].x&&C[x].x<=Q[i].y){ if(--c[a[C[x].x]]==0)tot--; if(++c[C[x].y]==1)tot++; } swap(a[C[x].x],C[x].y); } inline void add(int x) {if(++c[a[x]]==1)tot++;} inline void del(int x) {if(--c[a[x]]==0)tot--;} inline void work() { sort(Q+1,Q+qn+1);int now=0; for(int i=1;i<=qn;i++){ while(L<Q[i].x)del(L++); while(L>Q[i].x)add(--L); while(R<Q[i].y)add(++R); while(R>Q[i].y)del(R--); while(now<Q[i].id){change(++now,i);} while(now>Q[i].id){change(now--,i);} ans[Q[i].pos]=tot;} for(int i=1;i<=qn;i++) {print(ans[i]);*O++ = '\n';} } int main() { n=read();m=read(); for(int i=1;i<=n;i++)a[i]=read(); for(int i=1;i<=m;i++){ char ch[5];scanf("%s",ch); int x=read();int y=read(); if(ch[0]=='R'){C[++rn].x=x;C[rn].y=y;} else {Q[++qn].x=x;Q[qn].y=y; Q[qn].id=rn;Q[qn].pos=qn;}} s=ceil(exp((log(n)+log(qn))/3));L=1;R=0; work();fwrite(obuf, O-obuf, 1, stdout); return 0; }
蒟蒻写博客不易,如果有误还请大佬们提出
如需转载,请署名作者并附上原文链接,蒟蒻非常感激
名称:HolseLee
博客地址:www.cnblogs.com/cytus
个人邮箱:1073133650@qq.com
如需转载,请署名作者并附上原文链接,蒟蒻非常感激
名称:HolseLee
博客地址:www.cnblogs.com/cytus
个人邮箱:1073133650@qq.com