带修改的莫队算法
来源:互联网 发布:淘宝批发网叫什么 编辑:程序博客网 时间:2024/04/29 11:27
【前言】
普通的莫队算法固然强大,但是不能支持修改操作
于是就有了带修改莫队这种神奇的东西。
【做法】
普通的莫队可以看这里
那么对于询问的结构体,可以多记录一个信息ti
表示到这个询问为止最后做的修改的编号
至于排序么……与普通莫队类似,只是把ti作为第3个关键字
(当R在同一块的,就按ti排序)
处理时,要使当前区间,修改的指针一起动
(每次线性移动修改指针(修改/撤销),使得前ti个修改操作恰好被执行)
这样就完美解决了~~
【复杂度】
值得注意的是,带修改莫队的分块要分成
下面证明带修改莫队的复杂度
L指针:无论如何,对于每次询问,L最多移动
R指针:这里就比较复杂了,需要分情况讨论:
由于R是在每个L块上又分了
- 如果相邻两次询问使R没有跨越任何块,则最多走
N23 次,即O(QN23 ) - 跨越了R块,但处于同一L块,则最多走
N23 次,因为共有N13∗N13=N23 块,所以总复杂度为O(N43 ) - 跨越了L块,则最多走n次,即O(
N43 )
现在看t指针(修改操作)的移动:
1. 没有跨越任何块,每次N步,总复杂度O(
2. 跨越了R块,但处于同一L块,还是一样,总复杂度O(
3. 跨越了L块,也是一样的,只是L的块数是
所以说,如果N和Q是同一个级别的,复杂度就是O(这对于一个暴力来说已经很好了,大家可以在各大比赛中放心使用
【例题】
BZOJ2120
裸题……题解在这里
#include<cstdio>#include<algorithm>#include<cmath>using namespace std;const int maxn=10005,maxs=1000005;int n,q,h[maxn],a[maxn],b[maxn],hsh[maxs],topQ,topC,ans[maxn];struct ask{ int l,r,ti,id; bool operator<(const ask&b)const{ if (h[l]==h[b.l]){ if (h[r]==h[b.r]) return ti<b.ti; return r<b.r; } return l<b.l; }}que[maxn];struct cha{ int bf,af,i;}Ch[maxn];inline int red(){ int tot=0,f=1;char ch=getchar(); while (ch<'0'||'9'<ch) {if (ch=='-') f=-f;ch=getchar();} while ('0'<=ch&&ch<='9') tot=tot*10+ch-48,ch=getchar(); return tot*f;}inline char fstchar(){ char ch=getchar(); while (ch<'A'||'Z'<ch) ch=getchar(); return ch;}void blocker(){ int k=pow(n,2.0/3); for (int i=1;i<=n;i++) h[i]=(i-1)/k+1;}int now=0;void update(int x,int d){ if (d==1){ if (hsh[a[x]]==0) now++; hsh[a[x]]++; }else{ if (hsh[a[x]]==1) now--; hsh[a[x]]--; }}void change(int x,int w,int l,int r){ if (l<=x&&x<=r) update(x,-1),a[x]=w,update(x,1); else a[x]=w;}int main(){ n=red(),q=red(); blocker(); for (int i=1;i<=n;i++) a[i]=b[i]=red(); for (int i=1;i<=q;i++) if (fstchar()=='Q'){ que[++topQ].l=red(),que[topQ].r=red(); que[topQ].id=topQ;que[topQ].ti=topC; }else{ int x=red(),y=red(); Ch[++topC].bf=b[x];Ch[topC].af=y; b[x]=y;Ch[topC].i=x; } sort(que+1,que+1+topQ); update(1,1);change(Ch[1].i,Ch[1].af,1,1); for (int i=1,L=1,R=1,t=1;i<=topQ;i++){ while (t<que[i].ti) t++,change(Ch[t].i,Ch[t].af,L,R); while (t>que[i].ti) change(Ch[t].i,Ch[t].bf,L,R),t--; while (L<que[i].l) update(L++,-1); while (L>que[i].l) update(--L,1); while (R<que[i].r) update(++R,1); while (R>que[i].r) update(R--,-1); ans[que[i].id]=now; } for (int i=1;i<=topQ;i++) printf("%d\n",ans[i]); return 0;}
3 0
- 带修改的莫队算法
- 带修改的莫队算法学习小记
- BZOJ 2120: 数颜色 带修改的莫对算法
- bzoj 2120: 数颜色(带修改的莫队算法)
- 【JZOJ 4594】 Dynamic len &【JZOJ 2491】维护队列(带修改的莫队算法 模板)
- BZOJ 2120 数颜色——带修改的莫队算法
- 带修改的莫队算法【JZOJ 4594】【UVa 12345】Dynamic len
- BSOJ4559:数颜色 带修改莫队算法
- 树上(带修改)莫队算法-- bzoj4129 && bzoj3757
- [JZOJ4594] Dynamic len(带修改莫队算法模板)
- bzoj 2120: 数颜色 带修改莫队算法
- [BZOJ2120][带修改莫队算法]数颜色
- 【模板】带修改莫队
- BZOJ 3052 带修改的树上莫队
- [BZOJ 2120][数颜色][带修改的莫队]
- 带修改的树上莫队 WC糖果公园
- 带修改的莫队(日常普及知识)
- Dynamic len 题解+代码 (带修改莫队算法模板)
- LeetCode104 Maximum Depth of Binary Tree
- E45: 'readonly' option is set (add ! to override)
- 2017华为软件精英挑战赛参赛过程回顾与心得
- 失望
- RecyclerView更全解析之
- 带修改的莫队算法
- LeetCode105 Construct Binary Tree from Preorder and Inorder Traversal
- 常用正则表达式
- MATLAB中的varargin 函数
- angularJS 组件及内置过滤器
- 根据月份判断季节
- (更新于2017/10/14)TensorFlow在Windows环境下安装攻略(基于最新Anaconda3 5.0.0 )
- jsp九大内置对象详解
- RecyclerView更全解析之