【P1903】【BZOJ2120】[国家集训队]数颜色 修改莫队
2018-03-26 19:29
381 查看
题目描述
墨墨购买了一套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
题解
这道题属于典型的带修改莫队。 [带修改莫队学习笔记](https://blog.csdn.net/nlt_xxy/article/details/79689896)
代码
#include<iostream> #include<cstring> #include<cstdio> #include<cstdlib> #include<cmath> #include<algorithm> const int MAXN=1e6; using namespace std; int block,Qnum,Cnum; struct Query { int l,r,pre,Id; friend bool operator < (Query A,Query B) { if(A.l/block==B.l/block) return A.r<B.r; else return A.l/block<B.l/block; } }q[MAXN]; struct Change { int pos,num; }c[MAXN]; int n,m,answer,ans[MAXN],val[MAXN],cnt[MAXN]; inline int read() { int x=0; char ch=getchar(); while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x; } inline void Add(int x) { if(++cnt[val[x]]==1) answer++; } inline void Remove(int x) { if(--cnt[val[x]]==0) answer--; } inline void Change_(int now,int x) { if(c[now].pos>=q[x].l&&c[now].pos<=q[x].r) { //cout<<"0"; if(--cnt[val[c[now].pos]]==0) answer--; if(++cnt[c[now].num]==1) answer++; } swap(val[c[now].pos],c[now].num);//交换一下。 } void Moque() { int nowl=1,nowr=0,now=0; for(int i=1;i<=Qnum;i++) { while(nowl<q[i].l) Remove(nowl++); while(nowl>q[i].l) Add(--nowl); while(nowr<q[i].r) Add(++nowr); while(nowr>q[i].r) Remove(nowr--);//普通莫队模板 while(now<q[i].pre) Change_(++now,i);//修改莫队模板 while(now>q[i].pre) Change_(now--,i); // cout<<now<<" "; ans[q[i].Id]=answer; } for(int i=1;i<=Qnum;i++) { printf("%d\n",ans[i]); } return ; } int main() { scanf("%d%d",&n,&m); block=n/sqrt(n*2/3);//传说中优化常数的方法 for(int i=1;i<=n;i++) scanf("%d",&val[i]); for(int i=1;i<=m;i++) { char opt[5]; scanf("%s",opt); if(opt[0]=='Q') { q[++Qnum].l=read(); q[Qnum].r=read(); q[Qnum].pre=Cnum;//带修改莫队要记录离询问最近的修改 q[Qnum].Id=Qnum; // cout<<Qnum<<" "; } else if(opt[0]=='R') { c[++Cnum].pos=read(); c[Cnum].num=read(); } } // cout<<Cnum; //for(int i=1;i<=Qnum;i++) cout<<q[i].pre<<" "; sort(q+1,q+Qnum+1); Moque(); //system("pause"); return 0; }
相关文章推荐
- 【BZOJ 2120】【国家集训队 2011】【数颜色】
- [国家集训队][bzoj2120] 数颜色 [带修改莫队]
- 【BZOJ 2120】【国家集训队 2011】【数颜色】(莫队)
- P1903 [国家集训队]数颜色 带修改莫队板子
- 洛谷 P1903 BZOJ 2120 清橙 A1274【模板】分块/带修改莫队(数颜色)(周奕超)
- P1903 [国家集训队]数颜色
- 洛谷 P1903 [国家集训队]数颜色 带修改的莫队算法
- bzoj 2038: [2009国家集训队]小Z的袜子(hose)
- 【BZOJ 2120】 数颜色 (乱搞分块,直指暴力)
- 【bzoj2453】维护队列/【bzoj2120】数颜色 分块+二分
- BZOJ_2120_数颜色_Set+树状数组+主席树
- bzoj 2120 数颜色(可持久化莫队)
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose)(莫队算法)
- BZOJ 2120: 数颜色
- bzoj 2120 数颜色
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose)
- bzoj 2120 数颜色 树状数组套平衡树
- BZOJ.2134.[国家集训队]单选错位(概率 递推)
- bzoj 2038 [2009国家集训队]小Z的袜子(hose)
- 【bzoj2120】数颜色