记录编号 |
155273 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[WC 2013] 糖果公园 |
最终得分 |
100 |
用户昵称 |
new ioer |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
19.785 s |
提交时间 |
2015-03-28 08:40:33 |
内存使用 |
20.23 MiB |
显示代码纯文本
- #include<cmath>
- #include<cstdio>
- #include<algorithm>
- typedef long long lnt;
- const int maxn=100010,maxm=200010;
- bool vis[maxn];
- lnt ansnow,ans[maxn];
- char ch[10000000],*ptr=ch;
- int n,m,z,v[maxn],w[maxn],cnt[maxn],col[maxn],last[maxn];
- int len,sizen,cntblc,g[maxn],to[maxm],bel[maxn],next[maxm];
- int fa[maxn],sta[maxn],siz[maxn],son[maxn],dep[maxn],top[maxn];
- struct node{
- int u,v,id,tim;
- }q1[maxn],q2[maxn];
- void swap(int &x,int &y){
- x^=y,y^=x,x^=y;
- }
- void ins(int u,int v){
- to[++len]=v,next[len]=g[u],g[u]=len;
- }
- void in(int &x){
- x=0;
- while(*ptr<48) ptr++;
- while(*ptr>47) x=x*10+*ptr++-48;
- }
- void update(int x){
- if(vis[x]) ansnow-=(lnt)v[col[x]]*w[cnt[col[x]]--];
- else ansnow+=(lnt)v[col[x]]*w[++cnt[col[x]]];
- vis[x]^=1;
- }
- void modify(int u,int v){
- if(vis[u]) update(u),col[u]=v,update(u);
- else col[u]=v;
- }
- void moveto(int u,int v){
- while(u!=v)
- if(dep[u]>dep[v]) update(u),u=fa[u];
- else update(v),v=fa[v];
- }
- bool cmp(node a,node b){
- if(bel[a.u]!=bel[b.u]) return bel[a.u]<bel[b.u];
- if(bel[a.v]!=bel[b.v]) return bel[a.v]<bel[b.v];
- return a.id<b.id;
- }
- void getans(int i,int u){
- update(u);
- ans[q1[i].id]=ansnow;
- update(u);
- }
- int lca(int u,int v){
- for(int fu=top[u],fv=top[v];fu!=fv;u=fa[fu],fu=top[u])
- if(dep[fu]<dep[fv]) swap(fu,fv),swap(u,v);
- if(dep[u]<dep[v]) return u;
- return v;
- }
- void dfs(int x){
- sta[++sta[0]]=x;
- for(int p,i=g[x];i;i=next[i]){
- if((p=to[i])==fa[x]) continue;
- dfs(p),siz[x]+=siz[p];
- if(siz[x]>sizen){
- siz[x]=0,cntblc++;
- while(sta[sta[0]]!=x) bel[sta[sta[0]--]]=cntblc;
- }
- }
- siz[x]++;
- }
- void init(){
- int i,u,vv,x,p;
- in(n),in(m),in(z),sizen=(int)pow(n,2.0/3.0)*.5;
- for(i=1;i<=m;i++) in(v[i]);
- for(i=1;i<=n;i++) in(w[i]);
- for(i=1;i<n;i++) in(u),in(vv),ins(u,vv),ins(vv,u);
- for(i=1;i<=n;i++) in(col[i]),last[i]=col[i];
- u=1,vv=1,sta[1]=1;
- while(u<=vv){
- x=sta[u++],siz[x]=1;
- for(i=g[x];i;i=next[i])
- if((p=to[i])!=fa[x])
- dep[p]=dep[x]+1,fa[p]=x,sta[++vv]=p;
- }
- for(i=n;i;i--){
- x=sta[i],siz[fa[x]]+=siz[x];
- if(siz[x]>siz[son[fa[x]]]) son[fa[x]]=x;
- }
- for(i=1;i<=n;i++){
- x=sta[i],siz[x]=0;
- if(son[fa[x]]==x) top[x]=top[fa[x]];
- else for(top[x]=x;x;x=son[x]);
- }
- dfs(1),cntblc++;
- while(sta[0]) bel[sta[sta[0]--]]=cntblc;
- }
- void work(){
- int i,u,vv,cmd,totq=0,totc=0,timnow=1;
- for(i=1;i<=z;i++){
- in(cmd),in(u),in(vv);
- if(cmd){
- totq++;
- if(bel[u]>bel[vv]) swap(u,vv);
- q1[totq]=(node){u,vv,totq,totc};
- }
- else q2[++totc].id=u,q2[totc].u=last[u],q2[totc].v=last[u]=vv;
- }
- std::sort(q1+1,q1+totq+1,cmp);
- while(timnow<=q1[1].tim) modify(q2[timnow].id,q2[timnow].v),timnow++;
- moveto(q1[1].u,q1[1].v),getans(1,lca(q1[1].u,q1[1].v));
- for(i=2;i<=totq;i++){
- while(timnow<=q1[i].tim) modify(q2[timnow].id,q2[timnow].v),timnow++;
- while(timnow>q1[i].tim+1)modify(q2[timnow-1].id,q2[timnow-1].u),timnow--;
- 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));
- }
- for(i=1;i<=totq;i++) printf("%lld\n",ans[i]);
- }
- int main(){
- freopen("park.in" ,"r",stdin );
- freopen("park.out","w",stdout);
- fread(ch,1,10000000,stdin);
- init();
- work();
- return 0;
- }