BZOJ 2120 数颜色&2453 维护队列 [带修改的莫队算法]【学习笔记】
2017-03-17 20:30
483 查看
题意:
询问区间中不同颜色的个数,单点修改颜色
发现以前写的学习笔记没法看,于是重写一下(不就是会用latex了嘛)
额外维护一个当前修改操作执行到的时间
如果要进行某个查询操作,修改操作的时间必须移动到这个查询操作处
按照$(pos[l], pos[r], tim)$排序
令$S=N^{\frac{2}{3}}$, 有$N^{\frac{1}{3}}$块,假设$N,Q$同阶
$l$移动$N*N^{\frac{2}{3}}$次 因为每次移动无论块内还是块间都是最多$N^{\frac{2}{3}}$
$r$移动$N*N^{\frac{2}{3}}$次 和$l$一样,只不过$l$块间移动时$r$也会移动,貌似这一步的复杂度是$O(N)$
$cur$移动$N*N^{\frac{1}{3}}*N^{\frac{1}{3}}$次,$l,r$共有$N^{\frac{2}{3}}$种不同的可能,每种$cur$最坏移动$O(N)$
注意排序一定排对了啊啊啊啊
询问区间中不同颜色的个数,单点修改颜色
发现以前写的学习笔记没法看,于是重写一下(不就是会用latex了嘛)
额外维护一个当前修改操作执行到的时间
如果要进行某个查询操作,修改操作的时间必须移动到这个查询操作处
按照$(pos[l], pos[r], tim)$排序
令$S=N^{\frac{2}{3}}$, 有$N^{\frac{1}{3}}$块,假设$N,Q$同阶
$l$移动$N*N^{\frac{2}{3}}$次 因为每次移动无论块内还是块间都是最多$N^{\frac{2}{3}}$
$r$移动$N*N^{\frac{2}{3}}$次 和$l$一样,只不过$l$块间移动时$r$也会移动,貌似这一步的复杂度是$O(N)$
$cur$移动$N*N^{\frac{1}{3}}*N^{\frac{1}{3}}$次,$l,r$共有$N^{\frac{2}{3}}$种不同的可能,每种$cur$最坏移动$O(N)$
注意排序一定排对了啊啊啊啊
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; typedef long long ll; const int N=1e4+5, M=1e6+5; inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } int n,Q,a ,pos ,m,block,t ,x,y; char op[3]; struct meow{ int l,r,tim,id; bool operator <(const meow &a) const{ return pos[l]==pos[a.l] ? ( pos[r]==pos[a.r] ? tim<a.tim : pos[r]<pos[a.r]) : pos[l]<pos[a.l]; } }q ; struct cmeow{int p,v,last;}cq ; int p,tim, ans ; int c[M], now; int l=1,r=0,cur=0; inline void add(int x) {now+= (++c[x])==1;} inline void del(int x) {now-= (--c[x])==0;} inline void cha(int p,int v){ if(l<=p && p<=r) add(v), del(a[p]); a[p]=v; } void modui(){ for(int i=1;i<=p;i++){ while(cur<q[i].tim) cur++, cha(cq[cur].p, cq[cur].v); while(cur>q[i].tim) cha(cq[cur].p, cq[cur].last), cur--; while(r<q[i].r) r++, add(a[r]); while(r>q[i].r) del(a[r]), r--; while(l<q[i].l) del(a[l]), l++; while(l>q[i].l) l--, add(a[l]); ans[ q[i].id ]=now; } } int main(){ //freopen("in","r",stdin); n=read(); Q=read(); block=sqrt(n); m=(n-1)/block+1; for(int i=1;i<=n;i++) a[i]=t[i]=read(), pos[i]=(i-1)/block+1; for(int i=1;i<=Q;i++){ scanf("%s",op); x=read(); y=read(); if(op[0]=='Q') q[++p]=(meow){x, y, tim, p}; else cq[++tim]=(cmeow){x, y, t[x]}, t[x]=y; } sort(q+1, q+1+p); modui(); for(int i=1;i<=p;i++) printf("%d\n",ans[i]); }
相关文章推荐
- bzoj2453 维护队列 & bzoj2120 数颜色 (带修改莫队)
- [BZOJ2120] 数颜色 && [bzoj2453] 维护队列(莫队 || 分块)
- Bzoj 2120: 数颜色 && 2453: 维护队列 莫队,分块,bitset
- 【BZOJ-2453&2120】维护队列&数颜色 分块 + 带修莫队算法
- BZOJ 2120: 数颜色/BZOJ 2453: 维护队列 带修改莫队
- BZOJ 2120: 数颜色&&2453: 维护队列【双倍经验】
- BZOJ 2120: 数颜色 && 2453: 维护队列 【带修莫队版题【也可以学黄学长分块
- 【BZOJ】【2120】数颜色 & 【2453】维护队列
- BZOJ2453: 维护队列&2120: 数颜色
- BZOJ 2453: 维护队列&&BZOJ 2120 数颜色 分块
- Bzoj 2453: 维护队列 && Bzoj 2120: 数颜色 分块,bitset
- [树状数组套权值线段树 || 分块] BZOJ 2120 数颜色 & BZOJ 2453 维护队列
- bzoj 2120: 数颜色(带修改的莫队算法)
- [BZOJ 2453]维护队列:带修改莫队
- BZOJ[2120]数颜色/BZOJ[2453]维护队列 分块
- 【BZOJ2120】数颜色-带修改莫队算法
- [bzoj2120][bzoj2453][莫队算法]数颜色
- 【JZOJ 4594】 Dynamic len &【JZOJ 2491】维护队列(带修改的莫队算法 模板)
- 【bzoj2453】维护队列/【bzoj2120】数颜色 分块+二分
- 【BZOJ】2120: 数颜色 带修改的莫队算法