记录编号 217903 评测结果 AAAAAAAATA
题目名称 [WC 2013] 糖果公园 最终得分 90
用户昵称 Gravatardashgua 是否通过 未通过
代码语言 C++ 运行时间 31.095 s
提交时间 2016-01-06 17:39:31 内存使用 15.37 MiB
显示代码纯文本
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>

template<class Num>void read(Num &x)
{
	char c; int flag = 1;	
	
	while((c = getchar()) < '0' || c > '9')
		if(c == '-') flag *= -1;
	x = c - '0';
	while((c = getchar()) >= '0' && c <= '9')
		x *= 10, x += c - '0';
	x *= flag;
}
template<class Num>void write(Num x)
{
	if(x == 0) {putchar('0'); return;}
	static char s[20]; int sl = 0;
	if(x < 0) x = -x, putchar('-');
	while(x) s[sl++] = x % 10 + '0', x /= 10;
	while(sl) putchar(s[--sl]);
}

const int maxn = 1e5 + 20, logN = 17;
#define X first
#define Y second

int n, m, q;
long long v[maxn];
int w[maxn];
int cnt[maxn];

std::pair<int,int> edge[maxn << 1];
int head[maxn], Es;
int fa[maxn], F[maxn][logN], dep[maxn];

int B[maxn], Bs, Bn;
int st[maxn], top, size[maxn];

long long Ans[maxn], ans;
int col[maxn], sta[maxn];

struct Query
{
	int u, v, a, b, t, id;
}query[maxn];

struct Operation
{
	int x, y, z;
}op[maxn];

int qs, os;

bool cmp(const Query &x,const Query &y)
{
	return x.a == y.a ? (x.b == y.b ? x.t < y.t : x.b < y.b) : x.a < y.a;
}
inline void newedge(int u,int v)
{
	edge[++Es] = std::make_pair(v, head[u]), head[u] = Es;
}
void dfs(int a,int Fa)
{
	fa[a] = Fa, dep[a] = dep[Fa] + 1;
	st[++top] = a;
	
	F[a][0] = fa[a];
	for(int i = 1; i < logN; i++)
		F[a][i] = F[F[a][i - 1]][i - 1];
	
	for(int i = head[a]; i; i = edge[i].Y)
	{
		int v = edge[i].X;
	
		if(v == Fa) continue;
		dfs(v, a), size[a] += size[v];
	
		if(size[a] >= Bs)
		{
			size[a] = 0, ++Bn;
			while(st[top] != a)
				B[st[top--]] = Bn;
		}
	}
	size[a]++;
}

inline void del(int a)
{
	if(sta[a])
	{
		ans -= v[col[a]] * w[cnt[col[a]]];
		cnt[col[a]] --;
	}
}
inline void ins(int a)
{
	if(sta[a])
	{
		cnt[col[a]] ++;
		ans += v[col[a]] * w[cnt[col[a]]];
	}
}
inline void rev(int a)
{
	del(a), sta[a] ^= 1, ins(a);
}
inline void update(int a,int v)
{
	del(a), col[a] = v, ins(a);
}
inline int getlca(int u,int v)
{
	if(dep[u] < dep[v]) std::swap(u, v);
	
	for(int i = logN - 1; i >= 0; i--)
		if(dep[F[u][i]] >= dep[v]) u = F[u][i];
	
	if(u == v) return u;
	
	for(int i = logN - 1; i >= 0; i--)
		if(F[u][i] != F[v][i]) u = F[u][i], v = F[v][i];
	
	return F[u][0];
}
inline void rot(int x,int y,int s)
{
	rev(getlca(x, s));
	rev(getlca(y, s));
	
	while(x != y)
	{
		if(dep[x] < dep[y]) std::swap(x, y);
		rev(x), x = fa[x];
	}
}
void solve()
{
	std::sort(query + 1, query + qs + 1, cmp);
	
	int u = 1, v = 1, t = os;
	
	rev(1);
	
	for(int i = 1; i <= qs; i++)
	{
		while(t < query[i].t)
			++t, update(op[t].x, op[t].y); 
		while(t > query[i].t)
			update(op[t].x, op[t].z), t--;
		
		rot(u, query[i].u, v);
		u = query[i].u;
		rot(v, query[i].v, u);
		v = query[i].v;
		
		Ans[query[i].id] = ans;
	}
	
	for(int i = 1; i <= qs; i++)
		write(Ans[i]), puts("");
}
void init()
{
	read(n), read(m), read(q);
	
	for(int i = 1; i <= m; i++) read(v[i]);
	for(int i = 1; i <= n; i++) read(w[i]);
	
	for(int i = 1, u, v; i < n; i++)
	{
		read(u), read(v);
		newedge(u, v), newedge(v, u);
	}
	
	Bs = pow(n + 1, (double) 2 / 3), dfs(1, 0);
	while(top) B[st[top--]] = Bn;
	
	for(int i = 1; i <= n; i++) read(col[i]);
	
	for(int i = 1, t, x, y; i <= q; i++)
	{
		read(t), read(x), read(y), t ^= 1;
		
		if(t == 0)
		{
			if(B[x] > B[y]) std::swap(x, y);
			query[++qs] = (Query){x, y, B[x], B[y], os, qs};
		}
		else
		{
			op[++os] = (Operation){x, y, col[x]};
			col[x] = y;
		}
	}
}
int main()
{
	freopen("park.in","r",stdin);
	freopen("park.out","w",stdout);

	init();
	
	solve();

	fclose(stdin);
	fclose(stdout);
	return 0;
}