隐藏页面特效

[莫队]

1|0莫队


1|1特点


是一种优雅的暴力

解决大部分区间离线问题的离线算法

主要思想为分块,将 n2 降为 nn

题目关键词包含n,m,k,并有多个询问Li,Ri,求区间内的...

1|2思想


相当于有两个指针L,R,若当前询问的区间为l[i],r[i]那么会分别将 L,Rl[i],r[i]的方向移动,并在移动时做出与题目要求相关的操作

1|3模板


int sz = sqrt(n);//每一块的大小为根号n for(int i=1;i<=n;i++) belong[i] = i / sz; //将每一个位置划分到对应的块里面去 sort();//先按照每次询问的左端点所在的块号排序,如果两个区间左端点所在的块相同,那么按照右端点小的在前 int L = 1,R = 0;//初始化两个指针,R = 0,是为了能将第一个添加进去 for(int i=1;i<=m;i++) { while(q[i].l < L) add(--L); while(q[i].l > L) sub(L++); while(q[i].r < R) sub(R--); while(q[i].r > R) add(++R); ans[q[i].id] = res;//q[i].id表示原来它是第几次询问,因为要跟询问顺序保持一致,res为每次更新区间之后的答案 }

洛谷P2709 code

#include <cmath> #include <cstdio> #include <iostream> #include <algorithm> typedef long long LL; using namespace std; const int maxn = 5e4+5; int n,m,k,a[maxn],belong[maxn],cnt[maxn]; LL res,ans[maxn]; struct range{ int l,r,id; }q[maxn]; bool cmp(range x,range y) { return belong[x.l] == belong[y.l] ? x.r < y.r : belong[x.l] < belong[y.l]; } void add(int x) { res = res + 2 * cnt[a[x]] + 1; cnt[a[x]] ++; return ; } void sub(int x) { res = res - 2 * cnt[a[x]] + 1; cnt[a[x]] --; return ; } int main() { scanf("%d%d%d",&n,&m,&k); int sz = sqrt(n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); belong[i] = i / sz; } for(int i=1;i<=m;i++) { scanf("%d%d",&q[i].l,&q[i].r); q[i].id = i; } sort(q+1,q+m+1,cmp); int L = 1,R = 0; for(int i=1;i<=m;i++) { while(q[i].l < L) add(--L); while(q[i].l > L) sub(L++); while(q[i].r < R) sub(R--); while(q[i].r > R) add(++R); ans[q[i].id] = res; } for(int i=1;i<=m;i++) printf("%lld\n",ans[i]); return 0; }

2|0带修改的莫队


2|1区别


相比于普通莫队,多了在查询期间的修改操作,做法是开另一个数组记录是第几次修改了,如果当前的查询发生在第n次修改之后,那么就进行到第n次修改的状态,如果当前少于n次修改那么就前进直到修改到n次,如果当前修改次数多于n次,那么就后退直到后退为n次。

洛谷P1903 code

这个题十分毒瘤,卡常卡的给我T飞了,关键点是:1、原先块的大小为 n 修改为n34,其他指数应该也行,但我只测了0.66和0.75发现0.75要快不少;2、修改cmp函数若左端点所在的块相同,找右端点所在块,若都相同则按照修改次数小的排序,3、快读;剩下的就改改add(),sub()还有新加的修改操作update()

#include <cmath> #include <cctype> #include <cstdio> #include <iostream> #include <algorithm> typedef long long LL; using namespace std; const int maxn = 133336; int n,m,k,a[maxn],belong[maxn],num,cntm,now_up; int res,cnt[maxn*10],ans[maxn]; struct Q{ int l,r,id,up_cnt; }q[maxn]; struct R{ int val,pos; }up[maxn]; bool cmp(Q x,Q y) { return (belong[x.l] ^ belong[y.l]) ? belong[x.l] < belong[y.l] : ((belong[x.r] ^ belong[y.r]) ? belong[x.r] < belong[y.r] : x.up_cnt < y.up_cnt); } void add(int x) { if(!cnt[a[x]]) res ++; cnt[a[x]] ++; return ; } void sub(int x) { cnt[a[x]] --; if(!cnt[a[x]]) res --; return ; } void update(int x,int L,int R) { if(up[x].pos >= L && up[x].pos <= R) { cnt[a[up[x].pos]] --; if(!cnt[a[up[x].pos]]) res --; if(!cnt[up[x].val]) res ++; cnt[up[x].val] ++; } swap(a[up[x].pos],up[x].val);//给他“反悔”的机会,比如第二次修改时把当前位置的3改为9,那么如果要再倒回第二次修改之前,直接将两个交换,下次就是将9改为3 return ; } inline int read() { int x = 0,f = 1; char c; while(!isdigit(c=getchar())) if(c == '-') f = -1; while(isdigit(c)) x = (x<<3) + (x<<1) + (c&15),c = getchar(); return x * f; } inline void write(int x) { if(x < 0) { putchar('-'); write(~x+1); } else { if(x > 9) write(x/10); putchar(x%10+'0'); } return ; } int main() { n = read(); m = read(); int sz = pow(n,0.75); for(int i=1;i<=n;i++) { a[i] = read(); belong[i] = (i-1) / sz; } for(int i=1;i<=m;i++) { char c; cin >> c; if(c == 'Q') { cntm ++; q[cntm].l = read(); q[cntm].r = read(); q[cntm].id = cntm; q[cntm].up_cnt = num; } if(c == 'R') { num ++; up[num].pos = read(); up[num].val = read(); } } sort(q+1,q+cntm+1,cmp); int L = 1,R = 0; for(int i=1;i<=cntm;i++) { while(q[i].l < L) add(--L); while(q[i].l > L) sub(L++); while(q[i].r < R) sub(R--); while(q[i].r > R) add(++R); while(now_up < q[i].up_cnt) update(++now_up,L,R); while(now_up > q[i].up_cnt) update(now_up--,L,R); ans[q[i].id] = res; } for(int i=1;i<=cntm;i++) { write(ans[i]); printf("\n"); } return 0; }

__EOF__

本文作者风丨铃
本文链接https://www.cnblogs.com/-Wind-/p/18044423.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   风丨铃  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示