[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] 糖果公园 [树上带修改莫队]的主要内容,如果未能解决你的问题,请参考以下文章