bzoj3052: [wc2013]糖果公园

Description

 

Input

Output

 

Sample Input

Sample Input

 

Sample Output

84
131
27
84

HINT

 


 

vfk糖果公园的题解

http://vfleaking.blog.163.com/blog/static/174807634201311011201627/

 

code:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #define maxn 100005
 7 using namespace std;
 8 typedef long long int64;
 9 char ch;
10 int n,m,q,cnt1,cnt2,idx,v[maxn],w[maxn];
11 int siz,top,pos[maxn],col[maxn],t,x,y;
12 int64 ans[maxn],tmp;
13 int a,b,tot,now[maxn],son[maxn<<1],pre[maxn<<1];
14 int cnt[maxn],fa[maxn][18],stack[maxn],dep[maxn];
15 struct Change{
16     int x,y;
17 }change[maxn];
18 struct query{
19     int l,r,t,id;
20 }list[maxn];
21 bool cmp(query a,query b){
22     if (pos[a.l]!=pos[b.l]) return pos[a.l]<pos[b.l];
23     if (pos[a.r]!=pos[b.r]) return pos[a.r]<pos[b.r];
24     return a.t<b.t;
25 }
26 bool ok,bo[maxn],flag[maxn];
27 void read(int &x){
28     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
29     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
30     if (ok) x=-x;
31 }
32 void pop(int sum){for (++idx;sum;sum--,pos[stack[top--]]=idx);}
33 void put(int a,int b){pre[++tot]=now[a],now[a]=tot,son[tot]=b;}
34 int dfs(int u){
35     for (int i=1;fa[fa[u][i-1]][i-1];i++) fa[u][i]=fa[fa[u][i-1]][i-1];
36     int sum=0;
37     for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
38         if (v!=fa[u][0]){
39             fa[v][0]=u,dep[v]=dep[u]+1,sum+=dfs(v);
40             if (sum>=siz) pop(sum),sum=0;
41         }
42     stack[++top]=u;
43     return sum+1;
44 }
45 void up(int &u,int dep){for (int i=17;dep;i--) if (dep>=(1<<i)) dep-=(1<<i),u=fa[u][i];}
46 int get_lca(int u,int v){
47     if (dep[u]<dep[v]) swap(u,v);
48     up(u,dep[u]-dep[v]);
49     if (u==v) return u;
50     for (int i=17;i>=0;i--) if (fa[u][i]!=fa[v][i]) u=fa[u][i],v=fa[v][i];
51     return fa[u][0];
52 }
53 void work(int u){
54     if (bo[u]) bo[u]=0,tmp-=1LL*v[col[u]]*w[cnt[col[u]]--];
55     else bo[u]=1,tmp+=1LL*v[col[u]]*w[++cnt[col[u]]];
56 }
57 void move(int u,int v){for (;u!=v;work(u),u=fa[u][0]) if (dep[u]<dep[v]) swap(u,v);}
58 void modify(int t){
59     if (bo[change[t].x]) work(change[t].x),swap(col[change[t].x],change[t].y),work(change[t].x);
60     else swap(col[change[t].x],change[t].y);
61 }
62 int main(){
63     read(n),read(m),read(q),siz=(int)pow(n,2.0/3.0);
64     for (int i=1;i<=m;i++) read(v[i]);
65     for (int i=1;i<=n;i++) read(w[i]);
66     for (int i=1;i<n;i++) read(a),read(b),put(a,b),put(b,a);
67     pop(dfs(1));
68     for (int i=1;i<=n;i++) read(col[i]);
69     for (int i=1;i<=q;i++){
70         read(t),read(x),read(y);
71         if (t) list[++cnt1]=(query){x,y,cnt2,i},flag[i]=1;
72         else change[++cnt2]=(Change){x,y};
73     }
74     sort(list+1,list+cnt1+1,cmp); t=0;
75     for (int i=1;i<=cnt1;i++){
76         int lca=get_lca(list[i].l,list[i].r);
77         move(list[i-1].l,list[i].l);
78         move(list[i-1].r,list[i].r);
79         work(lca);
80         for (;t<list[i].t;t++) modify(t+1);
81         for (;t>list[i].t;t--) modify(t);
82         ans[list[i].id]=tmp;
83         work(lca);
84     }
85     for (int i=1;i<=q;i++) if (flag[i]) printf("%lld\n",ans[i]);
86     return 0;
87 }

 

posted @ 2015-08-07 16:24  chenyushuo  阅读(270)  评论(0编辑  收藏  举报