题目链接:http://poj.org/problem?id=3237
分析:
练手题, 做模板。
#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
const int maxn = 1e4 + 100;
int Add[maxn<<2], Lg[maxn<<2], Sg[maxn<<2];
struct Edge
{
int u, v, w;
}edges[maxn];
vector<int> G[maxn];
int sz[maxn], deep[maxn], fa[maxn], son[maxn];
int p[maxn], fp[maxn], top[maxn], pos;
int n;
void dfs1(int u, int f, int d)
{
deep[u] = d;
fa[u] = f;
sz[u] = 1;
for(int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
if(v == f)
continue;
dfs1(v, u, d+1);
sz[u] += sz[v];
if(son[u]==-1 || sz[v]>sz[son[u]])
son[u] = v;
}
}
void dfs2(int u, int sp)
{
top[u] = sp;
p[u] = pos++;
fp[pos-1] = u;
if(son[u] != -1)
dfs2(son[u], sp);
for(int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
if(v==fa[u] || v==son[u])
continue;
dfs2(v, v);
}
}
void PushUp(int rt)
{
Lg[rt] = max(Lg[rt<<1], Lg[rt<<1|1]);
Sg[rt] = min(Sg[rt<<1], Sg[rt<<1|1]);
}
void PushDown(int rt)
{
if(Add[rt] != 0)
{
Add[rt<<1] ^= 1;
Add[rt<<1|1] ^= 1;
Lg[rt<<1] = -Lg[rt<<1];
Sg[rt<<1] = -Sg[rt<<1];
swap(Lg[rt<<1], Sg[rt<<1]);
Lg[rt<<1|1] = -Lg[rt<<1|1];
Sg[rt<<1|1] = -Sg[rt<<1|1];
swap(Lg[rt<<1|1], Sg[rt<<1|1]);
Add[rt] = 0;
}
}
void build(int l, int r, int rt)
{
Add[rt] = 0;
Lg[rt] = Sg[rt] = 0;
if(l == r)
{
return ;
}
int m = (l+r)>>1;
build(lson);
build(rson);
PushUp(rt);
}
void update_Change(int p, int c, int l, int r, int rt)
{
if(l == r)
{
Lg[rt] = Sg[rt] = c;
Add[rt] = 0;
return ;
}
PushDown(rt);
int m = (l+r)>>1;
if(p <= m)
update_Change(p, c, lson);
else
update_Change(p, c, rson);
PushUp(rt);
}
void update_Negate(int L, int R, int l, int r, int rt)
{
if(L<=l && r<=R)
{
Add[rt] ^= 1;
Lg[rt] = -Lg[rt];
Sg[rt] = -Sg[rt];
swap(Lg[rt], Sg[rt]);
return ;
}
PushDown(rt);
int m = (l+r)>>1;
if(L <= m)
update_Negate(L, R, lson);
if(R > m)
update_Negate(L, R, rson);
PushUp(rt);
}
int query(int L, int R, int l, int r, int rt)
{
if(L<=l && r<=R)
{
return Lg[rt];
}
PushDown(rt);
int m = (l+r)>>1;
int res = -10000000;
if(L <= m)
res = max(res, query(L, R, lson));
if(R > m)
res = max(res,query(L, R, rson));
PushUp(rt);
return res;
}
void Change_update(int u, int v)
{
int f1 = top[u], f2 = top[v];
while(f1 != f2)
{
if(deep[f1] < deep[f2])
{
swap(u, v);
swap(f1, f2);
}
update_Negate(p[f1], p[u], 1, n-1, 1);
u = fa[f1];
f1 = top[u];
}
if(u == v)//切记!!! 和点权更新是不一样
return ;
if(deep[u] > deep[v])
{
swap(u, v);
}
update_Negate(p[son[u]], p[v], 1, n-1, 1);//切记!!! 和点权更新是不一样
}
int Change_query(int u, int v)
{
int res = -10000000;
int f1 = top[u], f2 = top[v];
while(f1 != f2)
{
if(deep[f1] < deep[f2])
{
swap(u, v);
swap(f1, f2);
}
res = max(res, query(p[f1], p[u], 1, n-1, 1));
u = fa[f1];
f1 = top[u];
}
if(u == v)//切记!!! 和点权更新是不一样
return res;
if(deep[u] > deep[v])
{
swap(u, v);
}
res = max(res, query(p[son[u]], p[v], 1, n-1, 1));//切记!!! 和点权更新是不一样
return res;
}
void init()
{
for(int i = 0; i <= n; i++)
G[i].clear();
memset(son, -1, sizeof(son));
pos = 0;
}
int main()
{
int T, a, b, c;
char s[10];
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
init();
for(int i = 1; i < n; i++)
{
scanf("%d%d%d", &a, &b, &c);
G[a].push_back(b);
G[b].push_back(a);
edges[i].u = a;
edges[i].v = b;
edges[i].w = c;
}
dfs1(1, -1, 1);
dfs2(1, 1);
build(1, n-1, 1);
for(int i = 1; i < n; i++)
{
if(deep[edges[i].u] < deep[edges[i].v])
{
swap(edges[i].u, edges[i].v);
}
update_Change(p[edges[i].u], edges[i].w, 1, n-1, 1);
}
for(; ;)
{
scanf("%s", s);
if(s[0] == 'Q')
{
scanf("%d%d", &a, &b);
int res = Change_query(a, b);
printf("%d\n", res);
}
else if(s[0] == 'C')
{
scanf("%d%d", &a, &c);
update_Change(p[edges[a].u], c, 1, n-1, 1);
}
else if(s[0] == 'N')
{
scanf("%d%d", &a, &b);
Change_update(a, b);
}
else
{
break;
}
}
}
return 0;
}