#include <memory.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <iostream>
#include <stdio.h>
#include <stack>
#include <time.h>
using namespace std;
#define M(a) memset(a,0,sizeof(a))
typedef pair<int,int> PII;
const int N = 300000+5;
const int INF = -100000000;
typedef __int64 LL;
int max(int x,int y)
{
return x > y ? x : y;
}
class LinkCutTree
{
public:
int ch[N][2],fa[N],pp[N],SZ[N];//path parent
int Max[N],cost[N],lazy[N];
int rev[N];
int find_root(int cur)
{
while(fa[cur])cur = fa[cur];
return cur;
}
void Modify(int x,int k)//修改
{
if(x == 0) return;
cost[x] = cost[x] + k;
Max[x] = Max[x] + k;
lazy[x] = lazy[x] + k;
}
void Spread(int x)//伸展
{
if(x == 0) return;
if(lazy[x] != 0)
{
Modify(ch[x][0],lazy[x]);
Modify(ch[x][1],lazy[x]);
lazy[x] = 0;
}
if(rev[x] != 0)
{
if(ch[x][0] != 0) rev[ch[x][0]] ^=1;
if(ch[x][1] != 0) rev[ch[x][1]] ^=1;
swap(ch[x][0],ch[x][1]);
rev[x] = 0;
}
}
void update(int x)//更新
{
Max[x] = max(cost[x],max(Max[ch[x][0]],Max[ch[x][1]]));
return;
}
void rotate(int x,bool f)//旋转
{
int y = fa[x];
ch[y][!f] = ch[x][f];
fa[ch[x][f]] = y;
fa[x] = fa[y];
if(fa[x])ch[fa[y]][ch[fa[y]][1] == y] = x;
ch[x][f] = y;
fa[y] = x;
update(y);
}
void splay(int x)//
{
Spread(x);
int i1,i2,root = find_root(x);
if (root == x) return;
pp[x] = pp[root];
pp[root] = 0;
while(fa[x])
{
if(!fa[fa[x]])
{
Spread(fa[x]);
Spread(x);
rotate(x,ch[fa[x]][0] == x);
}
else
{
int y = fa[x],z = fa[y];
Spread(z);
Spread(y);
Spread(x);
int f = (ch[z][0] == y);
if(ch[y][f] == x)
{
rotate(x,!f);
rotate(x,f);
}
else
{
rotate(y,f);
rotate(x,f);
}
}
}
update(x);
}
//void Rev(int x) {rev[x] ^= 1;return;}
void access(int x)//
{
for(int pre = 0; x;)
{
splay(x);
fa[ch[x][1]] = 0;
pp[ch[x][1]] = x;
ch[x][1] = pre;
pp[pre] = 0;
fa[pre] = x;
pre = x;
update(x);
x = pp[x];
}
}
int paint_path(int a,int b,int c)//
{
if(a > b) swap(a,b);
access(a);
int ans = 0;
for(int pre = 0; b;)
{
splay(b);
if(pp[b] == 0)
{
Modify(pre,c);
Modify(ch[b][1],c);
cost[b] += c;
update(b);
}
fa[ch[b][1]] = 0;
pp[ch[b][1]] = b;
ch[b][1] = pre;
pp[pre] = 0;
fa[pre] = b;
pre = b;
update(b);
b = pp[b];
}
return ans;
}
int query_path(int a,int b)//
{
if(a > b) swap(a,b);
access(a);
int ans = 0;
for(int pre = 0; b;)
{
splay(b);
if(pp[b] == 0)
{
ans = max(cost[b],max(Max[ch[b][1]],Max[pre]));
}
fa[ch[b][1]] = 0;
pp[ch[b][1]] = b;
ch[b][1] = pre;
pp[pre] = 0;
fa[pre] = b;
pre = b;
update(b);
b = pp[b];
}
return ans;
}
int get_root(int x)//
{
access(x);
splay(x);
while(ch[x][0])
x = ch[x][0];
return x;
}
void cut(int x,int y)//
{
if(x == y) return;
access(x);
splay(x);
rev[x] ^=1;
access(y);
splay(y);
pp[ch[y][0]] = pp[y];
fa[ch[y][0]] = 0;
pp[y] = 0;
ch[y][0] = 0;
update(y);
}
void join(int x,int y)//
{
access(x);
splay(x);
rev[x] ^=1;
access(y);
splay(y);
rev[y] ^=1;
pp[x] = y;
return;
}
void init()
{
M(ch),M(fa);
M(lazy);
M(rev);
pp[0] = 0;
Max[0] = 0;
rev[0] = 0;
lazy[0] = 0;
}
} LCT;
struct Edge
{
int p,next;
} E[3 * N];
int head[N],cnt = 0;
void Init()
{
memset(head,-1,sizeof(head));
cnt = 0;
}
void add(int a,int b)
{
cnt++;
E[cnt].p = b;
E[cnt].next = head[a];
head[a] = cnt;
cnt++;
E[cnt].p = a;
E[cnt].next = head[b];
head[b] = cnt;
}
int S[N],sidx;
int ins[N];
void dfs()
{
int i,j,k;
memset(ins,0,sizeof(ins));
sidx = 0;
S[++sidx] = 1;
LCT.pp[1] = 0;
while(sidx > 0)
{
int cur = S[sidx];
if(ins[cur] == 0)
{
ins[cur] = 1;
for(i = head[cur]; i != -1; i = E[i].next)
{
int p = E[i].p;
if(ins[p] == 0)
{
LCT.pp[p] = cur;
S[++sidx] = p;
}
}
}
else
{
sidx--;
ins[cur] = 0;
}
}
}
inline int Scan()
{
int res = 0 , ch ;
while( !( ( ch = getchar() ) >= '0' && ch <= '9' ) )
{
if( ch == EOF ) return 1 << 30 ;
}
res = ch - '0' ;
while( ( ch = getchar() ) >= '0' && ch <= '9' )
res = res * 10 + ( ch - '0' ) ;
return res ;
}
int main()
{
int i,j,k;
int n;
while(scanf("%d",&n) != EOF)
{
LCT.init();
Init();
for(i = 1; i < n; i++)
{
int a,b;
a = Scan();
b = Scan();
add(a,b);
}
int tmp;
for(i = 1; i <= n; i++)
{
tmp = Scan();
LCT.cost[i] = tmp;
LCT.Max[i] = LCT.cost[i];
}
dfs();
int Q;
Q = Scan();
int cmd,w,x,y;
for(i = 1; i <= Q; i++)
{
cmd = Scan();
if(cmd == 1)
{
//scanf("%d %d",&x,&y);
x = Scan();
y = Scan();
if(LCT.get_root(x) != LCT.get_root(y))
LCT.join(x,y);
else printf("-1\n");
}
else if(cmd == 2)
{
//scanf("%d %d",&x,&y);
x = Scan();
y = Scan();
if(x != y && LCT.get_root(x) == LCT.get_root(y))
LCT.cut(x,y);
else printf("-1\n");
}
else if(cmd == 3)
{
//scanf("%d %d %d",&w,&x,&y);
w = Scan();
x = Scan();
y = Scan();
if(LCT.get_root(x) == LCT.get_root(y))
{
LCT.paint_path(x,y,w);
}
else printf("-1\n");
}
else
{
//scanf("%d %d",&x,&y);
x = Scan();
y = Scan();
if(LCT.get_root(x) == LCT.get_root(y))
printf("%d\n",LCT.query_path(x,y));
else printf("-1\n");
}
}
printf("\n");
}
return 0;
}
HDU 4010 Query on The Trees [2011 大连网络赛]
最新推荐文章于 2013-09-11 20:32:39 发布