bzoj2120 数颜色
来源:互联网 发布:乐视手机mac拨号 编辑:程序博客网 时间:2024/06/11 07:47
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
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
4
3
4
HINT
对于100%的数据,N≤10000,M≤10000,修改操作不多于1000次,所有的输入数据中出现的所有整数均大于等于1且不超过10^6。
正解:带修改莫队(分块好像也可以来着。。)以前一直以为莫队不能带修改,但当修改次数较少的时候,莫队其实也是一个不错的选择。。
只要记录每次询问之前需要的修改,没修改的就修改,不该修改的就撤回,这样就能够做出这题了。。排序时先按左端点所在块排序,再按右端点所在块排序,最后按需要修改的次数排序。具体操作看代码吧。。
//It is made by wfj_2048~#include <algorithm>#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <vector>#include <cmath>#include <queue>#include <stack>#include <map>#include <set>#define inf 1<<30#define il inline#define RG register#define ll long long#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)using namespace std;struct node1{ int x,y,last; }r[10010];struct node2{ int l,r,id,tim,bl,br; }q[10010];int a[1000010],c[1000010],ans[1000010],last[1000010],n,m,L,R,cnt1,cnt2,Ans,head,block;char ch[3];il int gi(){ RG int x=0,q=0; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); if (ch=='-') q=1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q ? -x : x;}il int cmp(const node2 &a,const node2 &b){ if (a.bl==b.bl && a.br==b.br) return a.tim<b.tim; if (a.bl==b.bl) return a.br<b.br; return a.bl<b.bl;}il void change(RG int x,RG int y){ if (L<=x && x<=R){c[a[x]]--; if (c[a[x]]==0) Ans--; a[x]=y;c[a[x]]++; if (c[a[x]]==1) Ans++; }else a[x]=y; return;}il void work(){ n=gi(),m=gi(); block=sqrt(n); for (RG int i=1;i<=n;++i) last[i]=a[i]=gi(); for (RG int i=1;i<=m;++i){scanf("%s",ch);if (ch[0]=='R'){ RG int x=gi(),col=gi(); r[++cnt1].x=x,r[cnt1].y=col,r[cnt1].last=last[x],last[x]=col; }else{ RG int l=gi(),r=gi(); q[++cnt2].l=l,q[cnt2].r=r,q[cnt2].id=cnt2; q[cnt2].tim=cnt1,q[cnt2].bl=(l-1)/block+1,q[cnt2].br=(r-1)/block+1;} } sort(q+1,q+cnt2+1,cmp); L=1,R=0,head=0,Ans=0; for (RG int i=1;i<=cnt2;++i){while (head<q[i].tim) head++,change(r[head].x,r[head].y);while (head>q[i].tim) change(r[head].x,r[head].last),head--;while (L>q[i].l){ L--,c[a[L]]++; if (c[a[L]]==1) Ans++; }while (R<q[i].r){ R++,c[a[R]]++; if (c[a[R]]==1) Ans++; }while (L<q[i].l){ c[a[L]]--; if (c[a[L]]==0) Ans--; L++; }while (R>q[i].r){ c[a[R]]--; if (c[a[R]]==0) Ans--; R--; }ans[q[i].id]=Ans; } for (RG int i=1;i<=cnt2;++i) printf("%d\n",ans[i]); return;}int main(){ File("color"); work(); return 0;}
0 0
- 【BZOJ2120】数颜色 循环
- [BZOJ2120]数颜色
- bzoj2120 数颜色 分块
- BZOJ2120数颜色
- 【bzoj2120】数颜色
- 【bzoj2120】 数颜色
- 【BZOJ2120】数颜色,带修莫队
- bzoj2120 数颜色
- 【bzoj2120】数颜色 莫队
- 【bzoj2120】数颜色
- bzoj2120 数颜色
- [带修莫队] BZOJ2120: 数颜色
- 【bzoj2120】数颜色
- BZOJ2120 数颜色 分块
- bzoj2120 数颜色 分块
- bzoj2120 数颜色(莫队)
- 【bzoj2120】数颜色
- BZOJ2120: 数颜色
- h5、原生
- [bzoj4700]适者
- substr_count计算***在某字符串中出现的次数;
- Protobuf3语言指南
- [bsoj1855] Fibonacci数列
- bzoj2120 数颜色
- Git 学习
- ob_start,ob_end_clean,ob_get_contents函数
- 使用Struts2的输入校验(三)--短路校验器
- 二项式定理
- 面向对象的特征之三多态性
- js移动端双指缩放和旋转
- 最简单的加法运算1001,1002
- Jsp脚本段与声明的区别