Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions: 9123 | Accepted: 2411 |
Description
You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edges are numbered 1 through N − 1. Each edge is associated with a weight. Then you are to execute a series of instructions on the tree. The instructions can be one of the following forms:
CHANGE i v |
Change the weight of the ith edge to v |
NEGATE a b |
Negate the weight of every edge on the path from a to b |
QUERY a b |
Find the maximum weight of edges on the path from a to b |
Input
The input contains multiple test cases. The first line of input contains an integer t (t ≤ 20), the number of test cases. Then follow the test cases.
Each test case is preceded by an empty line. The first nonempty line of its contains N (N ≤ 10,000). The next N − 1 lines each contains three integers a, b and c, describing an edge connecting nodes a and b with weight c. The edges are numbered in the order they appear in the input. Below them are the instructions, each sticking to the specification above. A lines with the word “DONE
” ends the test case.
Output
For each “QUERY
” instruction, output the result on a separate line.
Sample Input
1 3 1 2 1 2 3 2 QUERY 1 2 CHANGE 1 3 QUERY 1 2 DONE
Sample Output
1 3
【分析】题意很好理解,唯一的难点就是将某一区间内的数变成相反数,需要用到懒惰标记。
#include <iostream> #include <cstring> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <time.h> #include <string> #include <map> #include <stack> #include <vector> #include <set> #include <queue> #define met(a,b) memset(a,b,sizeof a) #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; typedef long long ll; const int N=2e5+50; const int M=N*N+10; int dep[N],siz[N],fa[N],id[N],son[N],val[N],top[N]; //top 最近的重链父节点 int num,s,m,n,q; int sum[N*2],tre[2*N]; int maxn[N],minn[N],lazy[N]; vector<int> v[N]; struct tree { int x,y,val; void read() { scanf("%d%d%d",&x,&y,&val); } } e[N]; void dfs1(int u, int f, int d) { dep[u] = d; siz[u] = 1; son[u] = 0; fa[u] = f; for (int i = 0; i < v[u].size(); i++) { int ff = v[u][i]; if (ff == f) continue; dfs1(ff, u, d + 1); siz[u] += siz[ff]; if (siz[son[u]] < siz[ff]) son[u] = ff; } } void dfs2(int u, int tp) { top[u] = tp; id[u] = ++num; if (son[u]) dfs2(son[u], tp); for (int i = 0; i < v[u].size(); i++) { int ff = v[u][i]; if (ff == fa[u] || ff == son[u]) continue; dfs2(ff, ff); } } void ChangeVal(int rt) { int tmp=maxn[rt]; maxn[rt]=-minn[rt]; minn[rt]=-tmp; } void Push_up(int rt) { maxn[rt]=max(maxn[2*rt],maxn[2*rt+1]); minn[rt]=min(minn[2*rt],minn[2*rt+1]); } void Push_down(int rt) { if(lazy[rt]) { lazy[rt]^=1; lazy[2*rt]^=1; ChangeVal(rt*2); lazy[2*rt+1]^=1; ChangeVal(2*rt+1); } } void change(int t,int l,int r,int x,int v){ if(l==r) maxn[t]=minn[t]=v; else{ Push_down(t); int mid=(l+r)>>1; if(x<=mid) change(t*2,l,mid,x,v); else change(t*2+1,mid+1,r,x,v); Push_up(t); } } void Build(int l,int r,int rt) { if(l==r) { maxn[rt]=minn[rt]=val[l]; return; } int m=(l+r)>>1; Build(lson); Build(rson); Push_up(rt); //printf("rt=%d sum[rt]=%d ",rt,sum[rt]); } void Update(int L,int R,int l,int r,int rt) { if(l>=L&&r<=R) { lazy[rt]^=1; ChangeVal(rt); return; } Push_down(rt); int m=(r+l)>>1; if(L<=m)Update(L,R,lson); if(R>m) Update(L,R,rson); Push_up(rt); } int Query(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R)return maxn[rt]; Push_down(rt); int m=(l+r)>>1; if(R<=m)return Query(L,R,lson); else if(L>m)return Query(L,R,rson); else return max(Query(L,m,lson),Query(m+1,R,rson)); } void solve(int u, int v) { int tp1 = top[u], tp2 = top[v]; int ans = 0; while (tp1 != tp2) { if (dep[tp1] < dep[tp2]) { swap(tp1, tp2); swap(u, v); } Update(id[tp1],id[u],1,n,1); u = fa[tp1]; tp1 = top[u]; } if (u == v) return; if (dep[u] > dep[v]) swap(u, v); Update(id[son[u]],id[v],1,n,1); return; } int Yougth(int u,int v) { int tp1 = top[u], tp2 = top[v]; int ans=-10000000; while (tp1 != tp2) { if (dep[tp1] < dep[tp2]) { swap(tp1, tp2); swap(u, v); } ans = max(Query(id[tp1], id[u],1,n,1),ans); u = fa[tp1]; tp1 = top[u]; } if (u == v) return ans; if (dep[u] > dep[v]) swap(u, v); ans = max(Query(id[son[u]], id[v],1,n,1),ans); return ans; } void Clear(int n) { for(int i=1; i<=n; i++) v[i].clear(); met(son,0);met(maxn,0);met(minn,0); met(lazy,0); } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d",&n); Clear(n); int u,vv,w; for(int i=1; i<n; i++) { e[i].read(); v[e[i].x].push_back(e[i].y); v[e[i].y].push_back(e[i].x); } num = 0; dfs1(1,0,1); dfs2(1,1); for (int i = 1; i < n; i++) { if (dep[e[i].x] < dep[e[i].y]) swap(e[i].x, e[i].y); val[id[e[i].x]] = e[i].val; } Build(1,num,1); char str[20]; while(~scanf("%s",str)) { if(str[0]=='D')break; if(str[0]=='C') { scanf("%d%d",&u,&vv); if(dep[e[u].x]<dep[e[u].y])swap(e[u].x,e[u].y); change(1,1,n,id[e[u].x],vv); } else if(str[0]=='N'){ scanf("%d%d",&u,&vv); solve(u,vv); }else { scanf("%d%d",&u,&vv); if(u==vv)puts("0"); else printf("%d ",Yougth(u,vv)); } } } return 0; }