最裸的莫队:https://www.luogu.org/problemnew/show/P1494
#include<bits/stdc++.h> #define ll long long using namespace std; const int N=5e4+99; struct query{int l,r,id;ll a,b;}q[N]; int n,m,block,c[N],pos[N]; ll s[N],ans; bool cmp(query a,query b){return pos[a.l]<pos[b.l]||pos[a.l]==pos[b.l]&&a.r<b.r;} bool cmd(query a,query b){return a.id<b.id;} ll gcd(ll x,ll y){return y?gcd(y,x%y):x;} void update(int p,int add) { ans-=s[c[p]]*s[c[p]]; s[c[p]]+=add; ans+=s[c[p]]*s[c[p]]; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&c[i]); for(int i=1;i<=m;i++)scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i; block=floor(sqrt(n)+0.01); for(int i=1;i<=n;i++)pos[i]=(i-1)/block+1; sort(q+1,q+m+1,cmp); for(int i=1,l=1,r=0;i<=m;i++) { while(r<q[i].r)update(++r,1); while(r>q[i].r)update(r--,-1); while(l<q[i].l)update(l++,-1); while(l>q[i].l)update(--l,1); if(q[i].l==q[i].r){q[i].a=0;q[i].b=1;continue;} q[i].a=ans-(r-l+1); q[i].b=(ll)(r-l+1)*(r-l); ll t=gcd(q[i].a,q[i].b); q[i].a/=t;q[i].b/=t; } sort(q+1,q+m+1,cmd); for(int i=1;i<=m;i++)printf("%lld/%lld ",q[i].a,q[i].b); }
树上莫队:https://www.luogu.org/problemnew/show/P4074
#include<bits/stdc++.h> #define ll long long using namespace std; const int N=2e5+99; struct modify{int x,y,z;}p[N]; struct query{int l,r,k,lca,id;}q[N]; struct edge{int v,nxt;}e[N*2]; int n,m,Q,block,cnt,mdf,qry,hd[N],v[N],w[N],fa[N][20],deep[N],sum[N],pos[N],st[N],ed[N],col[N],dfx[N],lst[N]; ll ans[N],ret; bool vis[N]; bool cmp(query x,query y) { if(pos[x.l]!=pos[y.l])return pos[x.l]<pos[y.l]; if(pos[x.r]!=pos[y.r])return pos[x.r]<pos[y.r]; return x.k<y.k; } void add(int x,int y){e[++cnt]=(edge){y,hd[x]};hd[x]=cnt;} void dfs(int u) { st[u]=++cnt;dfx[cnt]=u; for(int i=hd[u];i;i=e[i].nxt) if(e[i].v!=fa[u][0]) fa[e[i].v][0]=u,deep[e[i].v]=deep[u]+1,dfs(e[i].v); ed[u]=++cnt;dfx[cnt]=u; } int lca(int x,int y) { if(deep[x]<deep[y])swap(x,y); int t=deep[x]-deep[y]; for(int i=0;(1<<i)<=t;i++)if(t&(1<<i))x=fa[x][i]; if(x==y)return x; for(int i=19;i>=0;i--) if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i]; return fa[x][0]; } void update(int x) { vis[x]^=1; if(vis[x])sum[col[x]]++,ret+=1ll*v[col[x]]*w[sum[col[x]]]; else ret-=1ll*v[col[x]]*w[sum[col[x]]],sum[col[x]]--; } void change(int x,int y) { if(vis[x])update(x),col[x]=y,update(x); else col[x]=y; return; } int main() { scanf("%d%d%d",&n,&m,&Q); block=pow(n,2.0/3)*0.52; for(int i=1;i<=m;i++)scanf("%d",&v[i]); for(int i=1;i<=n;i++)scanf("%d",&w[i]); for(int i=1,x,y;i<n;i++)scanf("%d%d",&x,&y),add(x,y),add(y,x); for(int i=1;i<=n;i++)scanf("%d",&col[i]),lst[i]=col[i]; cnt=0;dfs(1); for(int j=1;(1<<j)<=n;j++) for(int i=1;i<=n;i++) fa[i][j]=fa[fa[i][j-1]][j-1]; for(int i=1;i<=2*n;i++)pos[i]=i/block+1; for(int i=1,op,x,y;i<=Q;i++) { scanf("%d%d%d",&op,&x,&y); if(!op)p[++mdf]=(modify){x,lst[x],y},lst[x]=y; else{ if(st[x]>st[y])swap(x,y); int Fa=lca(x,y); if(x==Fa)q[++qry]=(query){st[x],st[y],mdf,0,qry}; else q[++qry]=(query){ed[x],st[y],mdf,Fa,qry}; } } sort(q+1,q+qry+1,cmp); for(int i=1,l=1,r=0,k=0;i<=qry;i++) { while(k<q[i].k)k++,change(p[k].x,p[k].z); while(k>q[i].k)change(p[k].x,p[k].y),k--; while(l>q[i].l)update(dfx[--l]); while(l<q[i].l)update(dfx[l++]); while(r<q[i].r)update(dfx[++r]); while(r>q[i].r)update(dfx[r--]); if(q[i].lca)update(q[i].lca); ans[q[i].id]=ret; if(q[i].lca)update(q[i].lca); } for(int i=1;i<=qry;i++)printf("%lld ",ans[i]); }
带修莫队:https://www.lydsy.com/JudgeOnline/problem.php?id=2120
#include<bits/stdc++.h> using namespace std; const int N=5e4+99; int n,m,cntq,cntc,block,a[N],pos[N],t[N],ret,ans[N],l,r,tim,cnt[N*20]; struct query{ int l,r,tm,id; bool operator<(const query&b)const { if(pos[l]!=pos[b.l])return pos[l]<pos[b.l]; if(pos[r]!=pos[b.r])return pos[r]<pos[b.r]; return tm<b.tm; } }q[N]; struct change{int x,ya,yb;}c[N]; void add(int p){if(!cnt[p])ret++;cnt[p]++;} void del(int p){cnt[p]--;if(!cnt[p])ret--;} void update1(change c) {if(l<=c.x&&c.x<=r)del(c.yb),add(c.ya);a[c.x]=c.ya;} void update2(change c) {if(l<=c.x&&c.x<=r)del(c.ya),add(c.yb);a[c.x]=c.yb;} int main() { scanf("%d%d",&n,&m); block=floor(sqrt(n)+0.01); for(int i=1;i<=n;i++)scanf("%d",&a[i]),t[i]=a[i],pos[i]=(i-1)/block+1; int x,y;char ch; for(int i=0;i<m;i++) { scanf(" %c%d%d",&ch,&x,&y); if(ch=='R')c[++cntc]={x,y,t[x]},t[x]=y; else q[++cntq]={x,y,cntc,cntq}; } sort(q+1,q+cntq+1); l=1,r=0,tim=0; for(int i=1;i<=cntq;i++) { while(tim<q[i].tm)update1(c[++tim]); while(tim>q[i].tm)update2(c[tim--]); while(r<q[i].r)add(a[++r]); while(r>q[i].r)del(a[r--]); while(l<q[i].l)del(a[l++]); while(l>q[i].l)add(a[--l]); ans[q[i].id]=ret; } for(int i=1;i<=cntq;i++)printf("%d ",ans[i]); }
回滚莫队:https://www.lydsy.com/JudgeOnline/problem.php?id=4241
#include<bits/stdc++.h> #define ll long long using namespace std; const int N=1e5+99; struct query{int l,r,id;}q[N]; int n,m,len,block,pos[N],a[N],v[N],num[N],num1[N]; ll ret,ans[N]; bool cmp(query x,query y){return pos[x.l]==pos[y.l]?x.r<y.r:pos[x.l]<pos[y.l];} void add(int p){ret=max(ret,1ll*(++num[p])*v[p]);} void del(int p){--num[p];} ll query(int l,int r) { ll mx=0; for(int i=l;i<=r;i++)mx=max(mx,1ll*(++num1[a[i]])*v[a[i]]); for(int i=l;i<=r;i++)--num1[a[i]]; return mx; } int update(int i,int blo) { int r=min(blo*block,n),l=r+1,L=l; memset(num,0,sizeof num); ret=0; for(;pos[q[i].l]==blo;i++) { if(pos[q[i].l]==pos[q[i].r])ans[q[i].id]=query(q[i].l,q[i].r); else{ while(r<q[i].r)add(a[++r]); ll tmp=ret; while(l>q[i].l)add(a[--l]); ans[q[i].id]=ret; while(l<L)del(a[l++]); ret=tmp; } } return i; } int main() { scanf("%d%d",&n,&m); block=sqrt(n+1); for(int i=1;i<=n;i++)scanf("%d",&a[i]),v[i]=a[i],pos[i]=(i-1)/block+1; sort(v+1,v+n+1); len=unique(v+1,v+n+1)-v-1; for(int i=1;i<=n;i++)a[i]=lower_bound(v+1,v+len+1,a[i])-v; 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); for(int now=1,i=1;i<=pos[n];i++)now=update(now,i); for(int i=1;i<=m;i++)printf("%lld ",ans[i]); }
二维莫队:https://www.lydsy.com/JudgeOnline/problem.php?id=2639
#include<bits/stdc++.h> #define rep(i,x,y) for(int i=x;i<=y;i++) #define y1 orz using namespace std; const int N=202,M=1e5; int n,m,Q,tot,sum,x1,y1,x2,y2,a[N][N],b[N*N],bel[N],cnt[N*N],ans[M]; struct query{ int x1,y1,x2,y2,id; bool operator<(const query&a)const{ if(bel[x1]!=bel[a.x1])return x1<a.x1; if(bel[y1]!=bel[a.y1])return y1<a.y1; if(bel[x2]!=bel[a.x2])return x2<a.x2; return y2<a.y2; } }q[M]; int sqr(int x){return x*x;} inline void modify_x(int x,int v) {rep(i,y1,y2)sum-=sqr(cnt[a[x][i]]),cnt[a[x][i]]+=v,sum+=sqr(cnt[a[x][i]]);} inline void modify_y(int y,int v) {rep(i,x1,x2)sum-=sqr(cnt[a[i][y]]),cnt[a[i][y]]+=v,sum+=sqr(cnt[a[i][y]]);} int main() { scanf("%d%d",&n,&m); rep(i,1,max(n,m))bel[i]=i/12; rep(i,1,n)rep(j,1,m)scanf("%d",&a[i][j]),b[++tot]=a[i][j]; sort(b+1,b+tot+1); tot=unique(b+1,b+tot+1)-b-1; rep(i,1,n)rep(j,1,m)a[i][j]=lower_bound(b+1,b+tot+1,a[i][j])-b; scanf("%d",&Q); rep(i,1,Q) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); if(x1>x2)swap(x1,x2);if(y1>y2)swap(y1,y2); q[i]=(query){x1,y1,x2,y2,i}; } sort(q+1,q+Q+1); x1=1,y1=1,x2=0,y2=0; rep(i,1,Q) { while(x1>q[i].x1)modify_x(--x1,1); while(x2<q[i].x2)modify_x(++x2,1); while(x1<q[i].x1)modify_x(x1++,-1); while(x2>q[i].x2)modify_x(x2--,-1); while(y1>q[i].y1)modify_y(--y1,1); while(y2<q[i].y2)modify_y(++y2,1); while(y1<q[i].y1)modify_y(y1++,-1); while(y2>q[i].y2)modify_y(y2--,-1); ans[q[i].id]=sum; } rep(i,1,Q)printf("%d ",ans[i]); }
按位分块:https://www.luogu.org/problemnew/show/CF472G
#include<bits/stdc++.h> using namespace std; const int N=2e5+7; int n1,n2,m,sz[65536]; unsigned a[32][N],b[32][N]; char s[N]; int count(unsigned x){return sz[x>>16]+sz[x&65535];} int main() { scanf("%s",s),n1=strlen(s); for(int j=0;j<32;j++)for(int i=0;i+j<n1;i++)a[j][i>>5]|=s[i+j]=='1'?1<<(i&31):0; scanf("%s",s),n2=strlen(s); for(int j=0;j<32;j++)for(int i=0;i+j<n2;i++)b[j][i>>5]|=s[i+j]=='1'?1<<(i&31):0; for(int i=0;i<65536;i++)sz[i]=sz[i>>1]+(i&1); scanf("%d",&m); while(m--) { int x,y,len,ans=0,i,j; scanf("%d%d%d",&x,&y,&len); for(i=x>>5,j=y>>5;len>=32;i++,j++,len-=32)ans+=count(a[x&31][i]^b[y&31][j]); ans+=count((a[x&31][i]^b[y&31][j])&((1<<len)-1)); printf("%d ",ans); } }
块状链表:咕