莫队算法入门
普通莫队:「BZOJ2038」小Z的袜子
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const int N=50010; 5 int n,m,c[N],bel[N],siz,cnt[N]; 6 ll ans1[N],ans2[N]; 7 ll gcd(ll x,ll y){return y?gcd(y,x%y):x;} 8 struct Node{ 9 int l,r,id; 10 bool operator<(const Node& k)const{return bel[l]==bel[k.l]?r<k.r:l<k.l;} 11 }que[N]; 12 int main(){ 13 scanf("%d%d",&n,&m); 14 siz=sqrt(n); 15 for(int i=1;i<=n;i++) scanf("%d",&c[i]),bel[i]=i/siz+1; 16 for(int i=1;i<=m;i++) scanf("%d%d",&que[i].l,&que[i].r),que[i].id=i; 17 sort(que+1,que+m+1); 18 int ql=1,qr=0; 19 ll sum1=0,sum2=0,len=0; 20 for(int i=1;i<=m;i++){ 21 while(qr<que[i].r){ 22 qr++; 23 sum1+=2*cnt[c[qr]],cnt[c[qr]]++; 24 sum2+=2*len,len++; 25 } 26 while(ql>que[i].l){ 27 ql--; 28 sum1+=2*cnt[c[ql]],cnt[c[ql]]++; 29 sum2+=2*len,len++; 30 } 31 while(qr>que[i].r){ 32 sum1-=2*cnt[c[qr]]-2,cnt[c[qr]]--; 33 sum2-=2*len-2,len--; 34 qr--; 35 } 36 while(ql<que[i].l){ 37 sum1-=2*cnt[c[ql]]-2,cnt[c[ql]]--; 38 sum2-=2*len-2,len--; 39 ql++; 40 } 41 if(que[i].l==que[i].r||!sum1) 42 ans1[que[i].id]=0,ans2[que[i].id]=1; 43 else{ 44 ll g=gcd(sum1,sum2); 45 ans1[que[i].id]=sum1/g,ans2[que[i].id]=sum2/g; 46 } 47 } 48 for(int i=1;i<=m;i++) printf("%lld/%lld\n",ans1[i],ans2[i]); 49 return 0; 50 }
带修改莫队:「BZOJ2120」数颜色
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=10010,C=1000010; 4 int n,m,siz,bel[N],color[N],temp[N],pos[N],from[N],to[N],cnt[C],totc,totq,ans[N]; 5 struct Q{ 6 int l,r,t,id;//查询[l,r]在t次修改后的信息 7 bool operator<(const Q& k)const{ 8 if(bel[l]==bel[k.l]&&bel[r]==bel[k.r]) return t<k.t; 9 if(bel[l]==bel[k.l]) return r<k.r; 10 return l<k.l; 11 } 12 }que[N]; 13 int main(){ 14 char opt[10]; 15 int t1,t2; 16 scanf("%d%d",&n,&m); 17 siz=pow(n,2.0/3); 18 for(int i=1;i<=n;i++) scanf("%d",&color[i]),temp[i]=color[i],bel[i]=i/siz+1; 19 for(int i=1;i<=m;i++){ 20 scanf("%s%d%d",opt,&t1,&t2); 21 if(opt[0]=='Q') que[++totq]=(Q){t1,t2,totc,totq}; 22 else totc++,pos[totc]=t1,to[totc]=t2,from[totc]=temp[t1],temp[t1]=t2; 23 } 24 sort(que+1,que+totq+1); 25 int pl=1,pr=0,pt=0,res=0; 26 for(int i=1;i<=totq;i++){ 27 while(pl>que[i].l){ 28 pl--; 29 cnt[color[pl]]++; 30 if(cnt[color[pl]==1]) res++; 31 } 32 while(pr<que[i].r){ 33 pr++; 34 cnt[color[pr]]++; 35 if(cnt[color[pr]]==1) res++; 36 } 37 while(pt<que[i].t){ 38 pt++; 39 if(pos[pt]<=pr&&pos[pt]>=pl){ 40 cnt[color[pos[pt]]]--; 41 if(!cnt[color[pos[pt]]]) res--; 42 } 43 color[pos[pt]]=to[pt]; 44 if(pos[pt]<=pr&&pos[pt]>=pl){ 45 cnt[color[pos[pt]]]++; 46 if(cnt[color[pos[pt]]]==1) res++; 47 } 48 } 49 while(pt>que[i].t){ 50 if(pos[pt]<=pr&&pos[pt]>=pl){ 51 cnt[color[pos[pt]]]--; 52 if(!cnt[color[pos[pt]]]) res--; 53 } 54 color[pos[pt]]=from[pt]; 55 if(pos[pt]<=pr&&pos[pt]>=pl){ 56 cnt[color[pos[pt]]]++; 57 if(cnt[color[pos[pt]]]==1) res++; 58 } 59 pt--; 60 } 61 while(pl<que[i].l){ 62 cnt[color[pl]]--; 63 if(!cnt[color[pl]]) res--; 64 pl++; 65 } 66 while(pr>que[i].r){ 67 cnt[color[pr]]--; 68 if(!cnt[color[pr]]) res--; 69 pr--; 70 } 71 ans[que[i].id]=res; 72 } 73 for(int i=1;i<=totq;i++) printf("%d\n",ans[i]); 74 return 0; 75 }
树上莫队:「UOJ58」[WC2013]糖果公园
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define R register 4 using namespace std; 5 const int N=100010,P=20,maxp=17; 6 inline int read(){ 7 int x=0;char c=0; 8 while(c<'0'||c>'9') c=getchar(); 9 while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar(); 10 return x; 11 } 12 int n,m,q,c[N],temp[N],id[N<<1],totid,siz,bel[N],in[N],out[N],cnt[N]; 13 short vis[N]; //vis[i]λiÔÚÅ·ÀÐòÖгöÏֵĴÎÊý 14 ll v[N],w[N],ans[N]; 15 vector<int>g[N]; 16 int f[N][P],dep[N]; 17 struct Que{ 18 int l,r,t,id;//²éѯŷÀÐòÖÐÇø¼ä[l,r]µÚt´ÎÐ޸ĺóµÄÐÅÏ¢ 19 bool operator<(const Que& k)const{ 20 if(bel[l]==bel[k.l]&&bel[r]==bel[k.r]) return t<k.t; 21 return bel[l]==bel[k.l]?r<k.r:l<k.l; 22 } 23 }que[N]; 24 int totq,totc,from[N],to[N],pos[N];//pos½ÚµãµÄÑÕÉ«´ÓfromÐÞ¸ÄΪto 25 void dfs(int k,int fa,int d){ 26 int x; 27 f[k][0]=fa,id[++totid]=k,dep[k]=d,in[k]=totid; 28 for(R int i=0;i<g[k].size();i++){ 29 x=g[k][i]; 30 if(x==fa) continue; 31 dfs(x,k,d+1); 32 } 33 id[++totid]=k,out[k]=totid; 34 return; 35 } 36 inline int getlca(int x,int y){ 37 if(dep[x]<dep[y]) swap(x,y); 38 for(int i=maxp;i>=0;i--) 39 if(dep[f[x][i]]>=dep[y]) x=f[x][i]; 40 if(x==y) return x; 41 for(int i=maxp;i>=0;i--) 42 if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i]; 43 return f[x][0]; 44 } 45 int main(){ 46 int opt,t1,t2; 47 n=read(),m=read(),q=read(),siz=pow(n,2.0/3); 48 for(R int i=1;i<=m;i++) v[i]=read(); 49 for(R int i=1;i<=n;i++) w[i]=read(),bel[i]=i/siz+1; 50 for(R int i=1;i<n;i++){t1=read(),t2=read();g[t1].push_back(t2);g[t2].push_back(t1);} 51 for(R int i=1;i<=n;i++) c[i]=read(),temp[i]=c[i]; 52 dfs(1,0,1); 53 for(R int j=1;j<=maxp;j++) 54 for(R int i=1;i<=n;i++) f[i][j]=f[f[i][j-1]][j-1]; 55 for(R int i=1;i<=q;i++){ 56 opt=read(),t1=read(),t2=read(); 57 if(!opt) ++totc,from[totc]=temp[t1],to[totc]=t2,pos[totc]=t1,temp[t1]=t2; 58 else{ 59 if(in[t1]>=in[t2]&&out[t1]<=out[t2]||in[t2]>=in[t1]&&out[t2]<=out[t1]) que[++totq]=(Que){min(in[t1],in[t2]),max(in[t1],in[t2]),totc,totq}; 60 else if(abs(in[t1]-out[t2])<abs(out[t1]-in[t2])) que[++totq]=(Que){min(in[t1],out[t2]),max(in[t1],out[t2]),totc,totq}; 61 else que[++totq]=(Que){min(in[t2],out[t1]),max(in[t2],out[t1]),totc,totq}; 62 } 63 } 64 sort(que+1,que+totq+1); 65 int lca; 66 R int x,pl=1,pr=0,pt=0; 67 R ll res=0; 68 for(R int i=1;i<=totq;i++){ 69 while(pl>que[i].l){ 70 x=id[--pl]; 71 if(!vis[x]) vis[x]=1,cnt[c[x]]++,res+=v[c[x]]*w[cnt[c[x]]]; 72 else if(vis[x]==1) res-=v[c[x]]*w[cnt[c[x]]],vis[x]=2,cnt[c[x]]--; 73 } 74 while(pr<que[i].r){ 75 x=id[++pr]; 76 if(!vis[x]) vis[x]=1,cnt[c[x]]++,res+=v[c[x]]*w[cnt[c[x]]]; 77 else if(vis[x]==1) res-=v[c[x]]*w[cnt[c[x]]],vis[x]=2,cnt[c[x]]--; 78 } 79 while(pt<que[i].t){ 80 pt++; 81 x=pos[pt]; 82 if(vis[x]==1) res-=v[c[x]]*w[cnt[c[x]]],cnt[c[x]]--; 83 c[x]=to[pt]; 84 if(vis[x]==1) cnt[c[x]]++,res+=v[c[x]]*w[cnt[c[x]]]; 85 } 86 while(pt>que[i].t){ 87 x=pos[pt]; 88 if(vis[x]==1) res-=v[c[x]]*w[cnt[c[x]]],cnt[c[x]]--; 89 c[x]=from[pt]; 90 if(vis[x]==1) cnt[c[x]]++,res+=v[c[x]]*w[cnt[c[x]]]; 91 pt--; 92 } 93 while(pl<que[i].l){ 94 x=id[pl]; 95 if(vis[x]==2) vis[x]=1,cnt[c[x]]++,res+=v[c[x]]*w[cnt[c[x]]]; 96 else if(vis[x]==1) res-=v[c[x]]*w[cnt[c[x]]],vis[x]=0,cnt[c[x]]--; 97 pl++; 98 } 99 while(pr>que[i].r){ 100 x=id[pr]; 101 if(vis[x]==2) vis[x]=1,cnt[c[x]]++,res+=v[c[x]]*w[cnt[c[x]]]; 102 else if(vis[x]==1) res-=v[c[x]]*w[cnt[c[x]]],vis[x]=0,cnt[c[x]]--; 103 pr--; 104 } 105 lca=getlca(id[que[i].l],id[que[i].r]); 106 if(lca==id[que[i].l]||lca==id[que[i].r]) ans[que[i].id]=res; 107 else ans[que[i].id]=res+v[c[lca]]*w[cnt[c[lca]]+1]; 108 } 109 for(R int i=1;i<=totq;i++) printf("%lld\n",ans[i]); 110 return 0; 111 }