You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1.node
We will ask you to perfrom some instructions of the following form:ios
The first line of input contains an integer t, the number of test cases (t <= 20). t test cases follow.ui
For each test case:spa
There is one blank line between successive tests.code
For each "QUERY" operation, write one integer representing its result.orm
Input: 1 3 1 2 1 2 3 2 QUERY 1 2 CHANGE 1 3 QUERY 1 2 DONE Output: 1 3
題意:blog
一棵樹有修改邊權值操做和詢問兩個節點之間的最大邊權值操做three
代碼:get
代碼:input
//每一個點和他父節點的邊構成一個線段樹上的點。因此線段樹的點實際從2開始 #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int MAXN=100000; int id[MAXN+9],fa[MAXN+9],max_val[MAXN*4+9],head[MAXN+9],son[MAXN+9],top[MAXN+9],lev[MAXN+9],size[MAXN+9]; //id:對應到線段樹上的點編號,son:重兒子,top:重鏈的頭,lev:深度,size:子樹大小 int tot,cnt,val[MAXN+9]; //cnt:線段樹節點數 struct Edge { int u,v,w,next; }edge[MAXN*2+9]; void init() { for(int i=0;i<=MAXN;i++) fa[i]=top[i]=i; memset(size,0,sizeof(size)); memset(head,-1,sizeof(head)); memset(val,0,sizeof(val)); tot=cnt=0; } void add(int x,int y,int z) { edge[tot].u=x;edge[tot].v=y;edge[tot].w=z; edge[tot].next=head[x]; head[x]=tot++; edge[tot].u=y;edge[tot].v=x;edge[tot].w=z; edge[tot].next=head[y]; head[y]=tot++; } void dfs1(int x,int d) { lev[x]=d; son[x]=0; size[x]=1; for(int i=head[x];i!=-1;i=edge[i].next){ int y=edge[i].v; if(y==fa[x]) continue; fa[y]=x; dfs1(y,d+1); size[x]+=size[y]; if(size[son[x]]<size[y]) son[x]=y; } } void dfs2(int x,int tp) { top[x]=tp; id[x]=++cnt; if(son[x]) dfs2(son[x],tp); for(int i=head[x];i!=-1;i=edge[i].next){ int y=edge[i].v; if(y==fa[x]||y==son[x]) continue; dfs2(y,y); } } void pushup(int rt) { max_val[rt]=max(max_val[rt<<1],max_val[rt<<1|1]); } void build(int l,int r,int rt) { if(l==r) { max_val[rt]=val[l];return; } int mid=(l+r)>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); pushup(rt); } void update(int id,int c,int l,int r,int rt) { if(l==r){ max_val[rt]=c; return; } int mid=(l+r)>>1; if(id<=mid) update(id,c,l,mid,rt<<1); else update(id,c,mid+1,r,rt<<1|1); pushup(rt); } int query(int ql,int qr,int l,int r,int rt) { if(ql<=l&&qr>=r) return max_val[rt]; int mid=(l+r)>>1,ans=0; if(ql<=mid) ans=max(ans,query(ql,qr,l,mid,rt<<1)); if(qr>mid) ans=max(ans,query(ql,qr,mid+1,r,rt<<1|1)); return ans; } int solve(int l,int r) { int ltp=top[l],rtp=top[r],ans=0; while(ltp!=rtp){ if(lev[rtp]<lev[ltp]){ swap(ltp,rtp); swap(l,r); } ans=max(ans,query(id[rtp],id[r],1,cnt,1)); r=fa[rtp]; rtp=top[r]; } if(lev[r]>lev[l]) swap(r,l); if(l!=r) ans=max(ans,query(id[son[r]],id[l],1,cnt,1)); return ans; } int main() { //freopen("in.txt","r",stdin); int t,n; scanf("%d",&t); while(t--){ init(); scanf("%d",&n); for(int i=1;i<n;i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); add(x,y,z); } dfs1(1,1); dfs2(1,1); for(int i=0;i<tot;i+=2){ if(lev[edge[i].u]>lev[edge[i].v]) swap(edge[i].u,edge[i].v); val[id[edge[i].v]]=edge[i].w; } build(1,cnt,1); char ch[20]; while(scanf("%s",ch)&&ch[0]!='D'){ int x,y; scanf("%d%d",&x,&y); if(ch[0]=='C') update(id[edge[x*2-2].v],y,1,cnt,1); else printf("%d\n",solve(x,y)); } } return 0; }