【bzoj 3052】: [wc2013]糖果公園


http://www.lydsy.com/JudgeOnline/problem.php?id=3052


題解啊。。。見vfk的。。。。

看了好久纔看懂啊。。。。。。。QwQ。。。

然後調了好久的參。。。


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <stack>
using namespace std;
#define rep(i,l,r) for(int i=(l),_=(r);i<=_;i++)
#define per(i,r,l) for(int i=(r),_=(l);i>=_;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define INE(i,u) for(int i=head[u];~i;i=e[i].next)
#define LL long long
inline const int read()
{int r=0,k=1;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}
////////////////////////////////////////////////
const int N=100010;
int n,m,q;
LL V[N],W[N];
struct edge{int v,next;}e[N*2];
int head[N],k;
LL ans[N];

int col[N],occur[N],vis[N]; // 顏色 出現次數 是否在鏈上 
struct query{int x,y,id,tm,pre;}Q[N],M[N];
int Q_cnt,M_cnt,tmp[N],ind;
int blk_sz,blk_cnt,belong[N];

stack<int>s;
int fa[N][17],sz[N],dep[N];

int curx,cury,curt;
LL curans;
////////////////////////////////////////////////
bool cmp(query A,query B)
{
	if(belong[A.x]!=belong[B.x]) return belong[A.x]<belong[B.x];
	if(belong[A.y]!=belong[B.y]) return belong[A.y]<belong[B.y];
	return A.tm<B.tm;
}
void adde(int u,int v){e[k]=(edge){v,head[u]};head[u]=k++;}
void dfs(int u)
{
	s.push(u);
	INE(i,u)
	{
		int v=e[i].v; if(v==fa[u][0]) continue;
		fa[v][0]=u; rep(i,1,16) fa[v][i]=fa[fa[v][i-1]][i-1];
		dep[v]=dep[u]+1;
		dfs(v);
		if(sz[u]+sz[v] >= blk_sz)
		{
			sz[u]=0;
			blk_cnt++;
			int v=0;
			while(u!=s.top())
			{
				v=s.top(); s.pop();
				belong[v]=blk_cnt;
			}
		}
		else sz[u]+=sz[v];
	}
	sz[u]++;
}
void reverse(int x)
{
	//printf("reverse:%d\n",x);
	if(vis[x]) curans-=W[occur[col[x]]]*V[col[x]] , occur[col[x]]--;
	else occur[col[x]]++ , curans+=W[occur[col[x]]]*V[col[x]];
	vis[x]^=1;
}
void move(int x,int y)
{
	if(x==y) return;
	for(;x^y;x=fa[x][0])
	{
		if(dep[x] < dep[y]) swap(x,y);
		reverse(x);
	}
}
void modify(int x,int c)
{
	if(vis[x])
	{
		reverse(x);
		col[x]=c;
		reverse(x);
	}
	else col[x]=c;
}
int getlca(int x,int y)
{
	if(dep[x]<dep[y]) swap(x,y);
	int d=dep[x]-dep[y];
	rep(i,0,16) if(d&1<<i) x=fa[x][i];
	if(x==y) return x;
	per(i,16,0) if(fa[x][i]^fa[y][i]) x=fa[x][i],y=fa[y][i];
	return fa[x][0];
}
////////////////////////////////////////////////
void input()
{
	MS(head,-1);
    n=read(); m=read(); q=read(); blk_sz=pow(n,0.66)*0.7;
    rep(i,1,m) V[i]=read();
    rep(i,1,n) W[i]=read();
    rep(i,2,n)
    {
    	int u=read(),v=read();
    	adde(u,v); adde(v,u);
    }
    rep(i,1,n) col[i]=tmp[i]=read();
	dfs(1);
	for(;!s.empty();s.pop()) belong[s.top()]=blk_cnt;
    rep(i,1,q)
    {
    	int t=read();
    	if(t)
    	{
    		Q_cnt++;
    		int x=read(),y=read();
    		if(belong[x]>belong[y]) swap(x,y);
    	    Q[Q_cnt].x=x; Q[Q_cnt].y=y; Q[Q_cnt].id=Q_cnt; Q[Q_cnt].tm=M_cnt;
    	}
    	else
    	{
    		M_cnt++;
    		int x=read(),y=read();
    		M[M_cnt].x=x; M[M_cnt].y=y;
			M[M_cnt].pre=tmp[x],tmp[x]=y;
    	}
    }
	sort(&Q[1],&Q[Q_cnt+1],cmp);
}
void solve()
{
	curx=1; cury=1; curt=0;
	rep(i,1,Q_cnt)
	{
		for(;curt>Q[i].tm;curt--) modify(M[curt].x,M[curt].pre);
		for(;curt<Q[i].tm;curt++) modify(M[curt+1].x,M[curt+1].y);
		move(curx,Q[i].x); curx=Q[i].x;
		move(cury,Q[i].y); cury=Q[i].y;
		
		int lca=getlca(Q[i].x,Q[i].y);
		reverse(lca);
		ans[Q[i].id]=curans;
		//printf("%d\n",Q[i].id);
		reverse(lca);
	}
	rep(i,1,Q_cnt) printf("%lld\n",ans[i]);
}
////////////////////////////////////////////////
int main()
{
    freopen("_.in","r",stdin); freopen("_.out","w",stdout);
    input(),solve();
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章