记录编号 155273 评测结果 AAAAAAAAAA
题目名称 [WC 2013] 糖果公园 最终得分 100
用户昵称 Gravatarnew ioer 是否通过 通过
代码语言 C++ 运行时间 19.785 s
提交时间 2015-03-28 08:40:33 内存使用 20.23 MiB
显示代码纯文本
  1. #include<cmath>
  2. #include<cstdio>
  3. #include<algorithm>
  4. typedef long long lnt;
  5. const int maxn=100010,maxm=200010;
  6. bool vis[maxn];
  7. lnt ansnow,ans[maxn];
  8. char ch[10000000],*ptr=ch;
  9. int n,m,z,v[maxn],w[maxn],cnt[maxn],col[maxn],last[maxn];
  10. int len,sizen,cntblc,g[maxn],to[maxm],bel[maxn],next[maxm];
  11. int fa[maxn],sta[maxn],siz[maxn],son[maxn],dep[maxn],top[maxn];
  12. struct node{
  13. int u,v,id,tim;
  14. }q1[maxn],q2[maxn];
  15. void swap(int &x,int &y){
  16. x^=y,y^=x,x^=y;
  17. }
  18. void ins(int u,int v){
  19. to[++len]=v,next[len]=g[u],g[u]=len;
  20. }
  21. void in(int &x){
  22. x=0;
  23. while(*ptr<48) ptr++;
  24. while(*ptr>47) x=x*10+*ptr++-48;
  25. }
  26. void update(int x){
  27. if(vis[x]) ansnow-=(lnt)v[col[x]]*w[cnt[col[x]]--];
  28. else ansnow+=(lnt)v[col[x]]*w[++cnt[col[x]]];
  29. vis[x]^=1;
  30. }
  31. void modify(int u,int v){
  32. if(vis[u]) update(u),col[u]=v,update(u);
  33. else col[u]=v;
  34. }
  35. void moveto(int u,int v){
  36. while(u!=v)
  37. if(dep[u]>dep[v]) update(u),u=fa[u];
  38. else update(v),v=fa[v];
  39. }
  40. bool cmp(node a,node b){
  41. if(bel[a.u]!=bel[b.u]) return bel[a.u]<bel[b.u];
  42. if(bel[a.v]!=bel[b.v]) return bel[a.v]<bel[b.v];
  43. return a.id<b.id;
  44. }
  45. void getans(int i,int u){
  46. update(u);
  47. ans[q1[i].id]=ansnow;
  48. update(u);
  49. }
  50. int lca(int u,int v){
  51. for(int fu=top[u],fv=top[v];fu!=fv;u=fa[fu],fu=top[u])
  52. if(dep[fu]<dep[fv]) swap(fu,fv),swap(u,v);
  53. if(dep[u]<dep[v]) return u;
  54. return v;
  55. }
  56. void dfs(int x){
  57. sta[++sta[0]]=x;
  58. for(int p,i=g[x];i;i=next[i]){
  59. if((p=to[i])==fa[x]) continue;
  60. dfs(p),siz[x]+=siz[p];
  61. if(siz[x]>sizen){
  62. siz[x]=0,cntblc++;
  63. while(sta[sta[0]]!=x) bel[sta[sta[0]--]]=cntblc;
  64. }
  65. }
  66. siz[x]++;
  67. }
  68. void init(){
  69. int i,u,vv,x,p;
  70. in(n),in(m),in(z),sizen=(int)pow(n,2.0/3.0)*.5;
  71. for(i=1;i<=m;i++) in(v[i]);
  72. for(i=1;i<=n;i++) in(w[i]);
  73. for(i=1;i<n;i++) in(u),in(vv),ins(u,vv),ins(vv,u);
  74. for(i=1;i<=n;i++) in(col[i]),last[i]=col[i];
  75. u=1,vv=1,sta[1]=1;
  76. while(u<=vv){
  77. x=sta[u++],siz[x]=1;
  78. for(i=g[x];i;i=next[i])
  79. if((p=to[i])!=fa[x])
  80. dep[p]=dep[x]+1,fa[p]=x,sta[++vv]=p;
  81. }
  82. for(i=n;i;i--){
  83. x=sta[i],siz[fa[x]]+=siz[x];
  84. if(siz[x]>siz[son[fa[x]]]) son[fa[x]]=x;
  85. }
  86. for(i=1;i<=n;i++){
  87. x=sta[i],siz[x]=0;
  88. if(son[fa[x]]==x) top[x]=top[fa[x]];
  89. else for(top[x]=x;x;x=son[x]);
  90. }
  91. dfs(1),cntblc++;
  92. while(sta[0]) bel[sta[sta[0]--]]=cntblc;
  93. }
  94. void work(){
  95. int i,u,vv,cmd,totq=0,totc=0,timnow=1;
  96. for(i=1;i<=z;i++){
  97. in(cmd),in(u),in(vv);
  98. if(cmd){
  99. totq++;
  100. if(bel[u]>bel[vv]) swap(u,vv);
  101. q1[totq]=(node){u,vv,totq,totc};
  102. }
  103. else q2[++totc].id=u,q2[totc].u=last[u],q2[totc].v=last[u]=vv;
  104. }
  105. std::sort(q1+1,q1+totq+1,cmp);
  106. while(timnow<=q1[1].tim) modify(q2[timnow].id,q2[timnow].v),timnow++;
  107. moveto(q1[1].u,q1[1].v),getans(1,lca(q1[1].u,q1[1].v));
  108. for(i=2;i<=totq;i++){
  109. while(timnow<=q1[i].tim) modify(q2[timnow].id,q2[timnow].v),timnow++;
  110. while(timnow>q1[i].tim+1)modify(q2[timnow-1].id,q2[timnow-1].u),timnow--;
  111. moveto(q1[i-1].u,q1[i].u),moveto(q1[i-1].v,q1[i].v),getans(i,lca(q1[i].u,q1[i].v));
  112. }
  113. for(i=1;i<=totq;i++) printf("%lld\n",ans[i]);
  114. }
  115. int main(){
  116. freopen("park.in" ,"r",stdin );
  117. freopen("park.out","w",stdout);
  118. fread(ch,1,10000000,stdin);
  119. init();
  120. work();
  121. return 0;
  122. }