Time Limit: 851MS | Memory Limit: 1572864KB | 64bit IO Format: %lld & %llu |
Description
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1.
We will ask you to perfrom some instructions of the following form:
The first line of input contains an integer t, the number of test cases (t <= 20). t test cases follow.
For each test case:
There is one blank line between successive tests.
For each "QUERY" operation, write one integer representing its result.
Input: 1 3 1 2 1 2 3 2 QUERY 1 2 CHANGE 1 3 QUERY 1 2 DONE Output: 1 3
【思路】
树链剖分。
划分轻重链,线段树维护。
这里有个知识入门:http://blog.sina.com.cn/s/blog_6974c8b20100zc61.html
【代码】
1 #include<cstdio> 2 #include<vector> 3 #include<cstring> 4 #include<algorithm> 5 #include<iostream> 6 using namespace std; 7 8 const int N = 20000+10; 9 10 struct Edge { int u,v,w; }; 11 vector<int> G[N]; 12 vector<Edge> es; 13 int n,z,root,d[N][3]; 14 int fa[N],siz[N],dep[N],son[N],w[N],top[N]; 15 //fa为父节点 siz为子树大小 dep为节点深度 16 //son代表重儿子 w为u与fa[u]在线段树中的位置 top代表所属重链的顶端 17 //z为线段树大小 18 19 void adde(int u,int v,int w) { 20 es.push_back((Edge){u,v,w}); 21 int m=es.size(); 22 G[u].push_back(m-1); 23 } 24 25 void dfs(int u) { //->siz[] son[] fa[] 26 siz[u]=1; son[u]=0; 27 for(int i=0;i<G[u].size();i++) { 28 int v=es[G[u][i]].v; 29 if(v!=fa[u]) { 30 fa[v]=u; 31 dep[v]=dep[u]+1; 32 dfs(v); 33 if(siz[v]>siz[son[u]]) son[u]=v; 34 siz[u]+=siz[v]; 35 } 36 } 37 } 38 void build_tree(int u,int tp) { //son[] -> top[] w[] 39 w[u]=++z; top[u]=tp; 40 if(son[u]) build_tree(son[u],top[u]); 41 for(int i=0;i<G[u].size();i++) { 42 int v=es[G[u][i]].v; 43 if(v!=son[u] && v!=fa[u]) build_tree(v,v); 44 } 45 } 46 47 int tree[N]; 48 void update(int u,int L,int R,int loc,int x) { 49 if(loc<L || R<loc) return ; 50 if(L==R) { tree[u]=x; return ; } 51 int M=L+(R-L)/2 , lc=u*2,rc=lc+1; 52 update(lc,L,M,loc,x); 53 update(rc,M+1,R,loc,x); 54 tree[u]=max(tree[lc],tree[rc]); 55 } 56 int query(int u,int L,int R,int l,int r) { 57 if(R<l || L>r) return 0; 58 if(l<=L && R<=r) return tree[u]; 59 int M=L+(R-L)/2; 60 return max(query(u*2,L,M,l,r),query(u*2+1,M+1,R,l,r)); 61 } 62 int find(int u,int v) { 63 int f1=top[u] , f2=top[v] , ans=0; 64 while(f1!=f2) { //直到移动到同一重链 65 if(dep[f1]<dep[f2]) 66 swap(f1,f2) , swap(u,v); 67 ans=max(ans,query(1,1,z,w[f1],w[u])); //在重链上移动同时统计 68 u=fa[f1] , f1=top[u]; 69 } 70 if(u==v) return ans; 71 if(dep[u]>dep[v]) swap(u,v); 72 return max(ans,query(1,1,z,w[son[u]],w[v])); //uv之间统计 73 } 74 75 void init() { 76 scanf("%d",&n); 77 es.clear(); 78 for(int i=0;i<=n;i++) G[i].clear(); 79 root=(n+1)/2; 80 fa[root]=dep[root]=z=0; 81 memset(siz,0,sizeof(siz)); 82 memset(tree,0,sizeof(tree)); 83 int u,v,c; 84 for(int i=1;i<n;i++) { 85 scanf("%d%d%d",&u,&v,&c); 86 d[i][0]=u , d[i][1]=v , d[i][2]=c; 87 adde(u,v,c) , adde(v,u,c); 88 } 89 dfs(root); 90 build_tree(root,root); 91 for(int i=1;i<n;i++) { 92 if(dep[d[i][0]]>dep[d[i][1]]) swap(d[i][0],d[i][1]); 93 update(1,1,z,w[d[i][1]],d[i][2]); 94 } 95 } 96 void solve() { 97 char s[20]; 98 int u,v; 99 while(scanf("%s",s)==1 && s[0]!='D') { 100 scanf("%d%d",&u,&v); 101 if(s[0]=='Q') printf("%d\n",find(u,v)); 102 else update(1,1,z,w[d[u][1]],v); 103 } 104 } 105 106 int main() { 107 int T; 108 scanf("%d",&T); 109 while(T--) { 110 init(); 111 solve(); 112 } 113 return 0; 114 }