莫队算法入门

普通莫队「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 }

 

posted @ 2018-03-08 16:43  Cupcake  阅读(144)  评论(0编辑  收藏  举报