[BZOJ2120]数颜色(带修改莫队)
2017-03-06 22:40
330 查看
题目描述
传送门题解
和BZOJ2453相同,在这里可以看到分块的做法而这道题同时又是一道带修莫队裸题
带修莫队大体方法如下:
1、将修改询问离线并分开,记录每一个修改之前最近的一次询问的编号
2、分块之后将区间排序,关键字为:左端点块的编号、右端点块的编号、记录的最近一次修改的编号
3、在查询每一次询问之前,判断当前做过的修改是否恰好是这次询问需要的修改,如果不够将其修改,修改多了的话恢复回去,注意如果修改的位置在前一个询问的区间内要更新答案
4、转移询问和普通莫队相同
代码
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> using namespace std; #define N 10005 int n,m,cq,cc,block,now,ans; struct data{int x,y,t,id,ans;}q ,ch ; int c ,num ,last ,cnt[N*100]; int cmp(data a,data b) { return num[a.x]<num[b.x]||(num[a.x]==num[b.x]&&num[a.y]<num[b.y])||(num[a.x]==num[b.x]&&num[a.y]==num[b.y]&&a.t<b.t); } void modui(int x,int y,int val) { for (int i=x;i<=y;++i) { if (val==1) { if (!cnt[c[i]]) ++ans; ++cnt[c[i]]; } else { --cnt[c[i]]; if (!cnt[c[i]]) --ans; } } } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=n;++i) scanf("%d",&c[i]); block=sqrt(n); for (int i=1;i<=n;++i) num[i]=(i-1)/block+1; for (int i=1;i<=m;++i) { char opt=getchar(); while (opt!='R'&&opt!='Q') opt=getchar(); if (opt=='R') { ++cc; scanf("%d %d",&ch[cc].x,&ch[cc].y); } else { ++cq;q[cq].id=cq; scanf("%d %d",&q[cq].x,&q[cq].y); q[cq].t=cc; } } sort(q+1,q+cq+1,cmp);now=q[1].t; for (int i=1;i<=q[1].t;++i) { last[i]=c[ch[i].x]; c[ch[i].x]=ch[i].y; } modui(q[1].x,q[1].y,1);q[q[1].id].ans=ans; for (int i=2;i<=cq;++i) { if (now<q[i].t) for (int j=now+1;j<=q[i].t;++j) { if (ch[j].x>=q[i-1].x&&ch[j].x<=q[i-1].y) { --cnt[c[ch[j].x]]; if (!cnt[c[ch[j].x]]) --ans; if (!cnt[ch[j].y]) ++ans; ++cnt[ch[j].y]; } last[j]=c[ch[j].x]; c[ch[j].x]=ch[j].y; } else if (now>q[i].t) for (int j=now;j>q[i].t;--j) { if (ch[j].x>=q[i-1].x&&ch[j].x<=q[i-1].y) { --cnt[c[ch[j].x]]; if (!cnt[c[ch[j].x]]) --ans; if (!cnt[last[j]]) ++ans; ++cnt[last[j]]; } c[ch[j].x]=last[j]; } now=q[i].t; if (q[i].x>q[i-1].x) modui(q[i-1].x,q[i].x-1,-1); else modui(q[i].x,q[i-1].x-1,1); if (q[i].y>q[i-1].y) modui(q[i-1].y+1,q[i].y,1); else modui(q[i].y+1,q[i-1].y,-1); q[q[i].id].ans=ans; } for (int i=1;i<=cq;++i) printf("%d\n",q[i].ans); }
相关文章推荐
- [国家集训队][bzoj2120] 数颜色 [带修改莫队]
- BZOJ2120 数颜色(带修改莫队)
- bzoj 2120 数颜色 带修改莫队
- bzoj 2120 数颜色 【带修改莫队模板】
- bzoj 2120: 数颜色(带修改的莫队算法)
- bzoj 2120 数颜色 待修改的莫队
- bzoj 2120 数颜色 带修改莫队
- bzoj 2120: 数颜色【带修改莫队】
- 【bzoj2120: 数颜色】带修改莫队
- bzoj2453 维护队列 & bzoj2120 数颜色 (带修改莫队)
- [BZOJ 2120][数颜色][带修改的莫队]
- bzoj2120 数颜色 带修改的莫队
- [BZOJ2120]数颜色(带修改莫队入门)
- [BZOJ 2120]数颜色:带修改莫队
- BZOJ 2120 数颜色——带修改的莫队算法
- BZOJ 2120: 数颜色/BZOJ 2453: 维护队列 带修改莫队
- [BZOJ2120]数颜色{带修改莫队}
- BZOJ 2120 数颜色(带修改莫队)
- BZOJ 2120 数颜色&2453 维护队列 [带修改的莫队算法]【学习笔记】
- [BZOJ2120][带修改莫队算法]数颜色