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: 13
题意:给你一棵树n个点n-1条边,有两个操作,一个操作是把改变某一条边的值,还有一个操作是询问书上两点间的路径中边的最大值。
思路:熟练剖分模板题,wa了很多发,最后发现是线段树写错了= =.
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<vector> #include<map> #include<set> #include<string> #include<bitset> #include<algorithm> using namespace std; #define lson th<<1 #define rson th<<1|1 typedef long long ll; typedef long double ldb; #define inf 999999999 #define pi acos(-1.0) #define maxn 10010 struct edge{ int next,to,len; }e[2*maxn]; int first[maxn]; int top[maxn]; //top[u]表示u所在的链的顶端节点 int son[maxn]; //son[u]表示u的重儿子 int fa[maxn],dep[maxn];//fa[u]表示u的父亲节点,dep[u]表示u在树中的深度 int num[maxn]; //num[u]表示u的子树的节点总个数 int p[maxn]; //p[u]表示u和其父亲节点的连边所在的线段树中区间的位置,这里先把重链都放在一起,然后再处理轻链。 void dfs1(int u,int pre,int deep) { int i,j,v; dep[u]=deep; num[u]=1; fa[u]=pre; for(i=first[u];i!=-1;i=e[i].next) { v=e[i].to; if(v==pre)continue; dfs1(v,u,deep+1); num[u]+=num[v]; if(son[u]==-1 || num[son[u] ]<num[v] ){ son[u]=v; } } } int pos; void dfs2(int u,int tp) { int i,j,v; top[u]=tp; if(son[u]!=-1){ p[u]=++pos; dfs2(son[u],tp); } else{ p[u]=++pos; return; } for(i=first[u];i!=-1;i=e[i].next){ v=e[i].to; if(v==fa[u] || v==son[u] )continue; dfs2(v,v); } } struct node{ int maxnum; }b[4*maxn]; void build(int L,int R,int th) { int i,j,mid; b[th].maxnum=0; if(L==R)return; mid=(L+R)/2; build(L,mid,lson); build(mid+1,R,rson); } void update(int idx,int num,int L,int R,int th) { int i,j,mid; if(idx==L && idx==R){ b[th].maxnum=num; return; } mid=(L+R)/2; if(idx<=mid)update(idx,num,L,mid,lson); else update(idx,num,mid+1,R,rson); b[th].maxnum=max(b[lson].maxnum,b[rson].maxnum); } int question(int l,int r,int L,int R,int th) { int i,j,mid; if(l==L && r==R){ return b[th].maxnum; } mid=(L+R)/2; if(r<=mid)return question(l,r,L,mid,lson); else if(l>mid)return question(l,r,mid+1,R,rson); else{ return max(question(l,mid,L,mid,lson),question(mid+1,r,mid+1,R,rson) ); } } int ed[maxn][3]; int fd(int u,int v) { int i,j; int f1,f2; int num=0; f1=top[u];f2=top[v]; while(f1!=f2){ if(dep[f1]<dep[f2]){ swap(f1,f2); swap(u,v); } num=max(num,question(p[f1],p[u],1,pos,1) ); u=fa[f1]; f1=top[u]; } if(u==v)return num; if(dep[u]<dep[v])swap(u,v); num=max(num,question(p[son[v] ],p[u],1,pos,1)); return num; } int main() { int m,i,j,T,c,d,g,tot,f,n; char s[10]; scanf("%d",&T); while(T--) { memset(first,-1,sizeof(first)); memset(son,-1,sizeof(son)); tot=0; pos=0; scanf("%d",&n); for(i=1;i<=n-1;i++){ scanf("%d%d%d",&c,&d,&g); ed[i][0]=c;ed[i][1]=d;ed[i][2]=g; tot++; e[tot].next=first[c];e[tot].to=d;e[tot].len=g; first[c]=tot; tot++; e[tot].next=first[d];e[tot].to=c;e[tot].len=g; first[d]=tot; } dfs1(1,0,1); dfs2(1,1); build(1,pos,1); for(i=1;i<=n-1;i++){ c=ed[i][0];d=ed[i][1]; if(dep[c ]<dep[d ]){ swap(c,d); } update(p[c],ed[i][2],1,pos,1); } while(1) { scanf("%s",s); if(s[0]=='D'){ break; } scanf("%d%d",&c,&d); if(s[0]=='C'){ f=ed[c][0];g=ed[c][1]; if(dep[f]<dep[g ]){ swap(f,g); } update(p[f],d,1,pos,1); } else if(s[0]=='Q'){ printf("%d\n",fd(c,d) ); } } } return 0; }