记录编号 155273 评测结果 AAAAAAAAAA
题目名称 [WC 2013] 糖果公园 最终得分 100
用户昵称 Gravatarnew 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;
}