[WC2013][luogu4074] 糖果公园 [树上带修改莫队]

Posted Orion545

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[WC2013][luogu4074] 糖果公园 [树上带修改莫队]相关的知识,希望对你有一定的参考价值。

题面:

传送门

思路:

一道实现起来细节比较恶心的题目

但是其实就是一个裸的树上带修改莫队

好像树上莫队也出不了什么结合题目,不像序列莫队天天结合AC自动机、后缀数组......

莫队学习请戳这里:莫队

Code:

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 #define ll long long
  7 using namespace std;
  8 inline ll read(){
  9     ll re=0,flag=1;char ch=getchar();
 10     while(ch>\'9\'||ch<\'0\'){
 11         if(ch==\'-\') flag=-1;
 12         ch=getchar();
 13     }
 14     while(ch>=\'0\'&&ch<=\'9\') re=(re<<1)+(re<<3)+ch-\'0\',ch=getchar();
 15     return re*flag;
 16 }
 17 struct edge{
 18     ll to,next;
 19 }a[200010];
 20 ll n,m,Q,first[100010],cntt,clk,block;
 21 ll fa[100010],dep[100010],st[100010][20],dfn[100010];
 22 ll v[100010],w[100010],x[100010];
 23 inline void add(ll u,ll v){
 24     a[++cntt]=(edge){v,first[u]};first[u]=cntt;
 25     a[++cntt]=(edge){u,first[v]};first[v]=cntt;
 26 }
 27 void dfs(ll u,ll f){
 28     //cout<<"dfs "<<u<<" "<<f<<"\\n";
 29     ll i,v;
 30     fa[u]=st[u][0]=f;dep[u]=dep[f]+1;dfn[u]=++clk;
 31     for(i=first[u];~i;i=a[i].next){
 32         v=a[i].to;
 33         if(v==f) continue;
 34         dfs(v,u);
 35     }
 36 }
 37 void init(){
 38     for(ll i=1;i<=18;i++){
 39         for(ll j=1;j<=n;j++){
 40             st[j][i]=st[st[j][i-1]][i-1];
 41         }
 42     }
 43 }
 44 void _swap(ll &l,ll &r){l^=r;r^=l;l^=r;}
 45 ll LCA(ll l,ll r){
 46     //cout<<"lca "<<l<<" "<<r<<"\\n";
 47     if(dep[l]>dep[r]) _swap(l,r);
 48     ll i;
 49     for(i=18;i>=0;i--) if(dep[st[r][i]]>=dep[l]) r=st[r][i];
 50     if(l==r) return l;
 51     for(i=18;i>=0;i--){
 52         if(st[l][i]!=st[r][i]){
 53             l=st[l][i];r=st[r][i];
 54         }
 55     }
 56     return fa[l];
 57 }
 58 ll curl,curr,curc,cntq,cntc,cnt[1000010];bool vis[100010];
 59 ll ans[100010],tot;
 60 struct query{
 61     ll l,r,c,i;
 62 }q[100010];
 63 bool cmp(query l,query r){
 64     if(dfn[l.l]/block!=dfn[r.l]/block) return dfn[l.l]/block<dfn[r.l]/block;
 65     else{
 66         if(dfn[l.r]/block!=dfn[r.r]/block) 
 67             return dfn[l.r]/block<dfn[r.r]/block;
 68         else return l.c<r.c;
 69     }
 70 }
 71 struct change{
 72     ll pos,to;
 73 }c[100010];
 74 void rev(ll i){
 75     if(vis[i]) vis[i]=0,tot-=v[x[i]]*w[cnt[x[i]]],cnt[x[i]]--;
 76     else vis[i]=1,cnt[x[i]]++,tot+=v[x[i]]*w[cnt[x[i]]];
 77     //cout<<"rev node "<<i<<" "<<x[i]<<" "<<tot<<"\\n";
 78 }
 79 void change(ll i){
 80     //cout<<"change node "<<i<<" "<<c[i].pos<<" "<<c[i].to<<"\\n";
 81     if(!vis[c[i].pos]) _swap(c[i].to,x[c[i].pos]);
 82     else{
 83         rev(c[i].pos);
 84         _swap(c[i].to,x[c[i].pos]);
 85         rev(c[i].pos);
 86     }
 87 }
 88 int main(){
 89     memset(first,-1,sizeof(first));
 90     ll i,t1,t2,t3;
 91     n=read();m=read();Q=read();block=(ll)pow(n,0.60);
 92     for(i=1;i<=m;i++) v[i]=read(); 
 93     for(i=1;i<=n;i++) w[i]=read();
 94     for(i=1;i<n;i++){
 95         t1=read();t2=read();add(t1,t2);
 96     }
 97     for(i=1;i<=n;i++) x[i]=read();
 98     dfs(1,0);init();
 99     //for(i=1;i<=n;i++) cout<<fa[i]<<" "<<dep[i]<<"\\n";
100     for(i=1;i<=Q;i++){
101         t1=read();t2=read();t3=read();
102         if(t1) q[++cntq].l=t2,q[cntq].r=t3,q[cntq].c=cntc,q[cntq].i=cntq;
103         else c[++cntc].pos=t2,c[cntc].to=t3;
104         //cout<<"finish read in "<<i<<"\\n";
105     }
106     sort(q+1,q+cntq+1,cmp);
107     //for(i=1;i<=cntq;i++) 
108         //cout<<q[i].l<<" "<<q[i].r<<" "<<q[i].c<<" "<<q[i].i<<"\\n";
109     
110     if(dfn[q[1].l]>dfn[q[1].r]) _swap(q[1].l,q[1].r);
111     ll lca=LCA(q[1].l,q[1].r),l,r;curl=q[1].l;curr=q[1].r;
112     l=curl;r=curr;
113     while(l!=lca) rev(l),l=fa[l];
114     while(r!=lca) rev(r),r=fa[r];
115     while(curc<q[1].c) change(++curc);
116     rev(lca);ans[q[1].i]=tot;rev(lca);
117     for(i=2;i<=cntq;i++){
118         //cout<<"i=="<<i<<"\\n";
119         if(dfn[q[i].l]>dfn[q[i].r]) _swap(q[i].l,q[i].r);
120         lca=LCA(curr,q[i].r);l=curr;r=q[i].r;
121         while(l!=lca) rev(l),l=fa[l];
122         while(r!=lca) rev(r),r=fa[r];
123         lca=LCA(curl,q[i].l);l=curl;r=q[i].l;
124         while(l!=lca) rev(l),l=fa[l];
125         while(r!=lca) rev(r),r=fa[r];
126         while(curc>q[i].c) change(curc--);
127         while(curc<q[i].c) change(++curc);
128         lca=LCA(q[i].l,q[i].r);
129         rev(lca);ans[q[i].i]=tot;rev(lca);
130         curl=q[i].l;curr=q[i].r;
131     }
132     for(i=1;i<=cntq;i++) printf("%lld\\n",ans[i]);
133 }

 

以上是关于[WC2013][luogu4074] 糖果公园 [树上带修改莫队]的主要内容,如果未能解决你的问题,请参考以下文章

LUOGU P4074 [WC2013]糖果公园

P4074 [WC2013]糖果公园

[WC2013][UOJ58]糖果公园 莫队算法

[BZOJ3052][UOJ#58][WC2013]糖果公园

WC2013 糖果公园 - 树上莫队

WC2013 糖果公园