SPOJ 375 Query on a tree【树链剖分】
题目大意:给你一棵树,有两个操作1.修改一条边的值,2.询问从x到y路径上边的最大值
思路:如果树退化成一条链的话线段树就很明显了,然后这题就是套了个树连剖分,调了很久终于调出来第一个模板了
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define maxn 100009 5 using namespace std; 6 int head[maxn],next[maxn*2],point[maxn],son[maxn],size_k[maxn],id[maxn],value[maxn],now=0,father[maxn],top[maxn]; 7 int x[maxn],y[maxn],v[maxn],tree[maxn*4],pos=0,deep[maxn],n; 8 int read() 9 { 10 int x=0,f=1;char ch=getchar(); 11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 12 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 13 return x*f; 14 } 15 void add(int x,int y,int v) 16 { 17 next[++now]=head[x];head[x]=now; 18 point[now]=y;value[now]=v; 19 } 20 int dfs(int k,int fa) 21 { 22 deep[k]=deep[fa]+1; 23 father[k]=fa; 24 size_k[k]=1; 25 int max_x=-1; 26 son[k]=-1; 27 for(int i=head[k];i;i=next[i]) 28 { 29 if(point[i]==fa)continue; 30 dfs(point[i],k); 31 size_k[k]+=size_k[point[i]]; 32 if(size_k[point[i]]>max_x) 33 { 34 max_x=size_k[point[i]]; 35 son[k]=point[i]; 36 } 37 } 38 } 39 void dfs2(int k,int fa,int pa) 40 { 41 id[k]=++pos; 42 top[k]=pa; 43 if(son[k]!=-1)dfs2(son[k],k,pa); 44 for(int i=head[k];i;i=next[i]) 45 { 46 if(point[i]!=fa && point[i]!=son[k])dfs2(point[i],k,point[i]); 47 } 48 } 49 void update(int node,int l,int r,int pos,int x) 50 { 51 if(l+1==r){tree[node]=x;return;} 52 int mid=(l+r)>>1; 53 if(pos<mid)update(node*2,l,mid,pos,x); 54 else update(node*2+1,mid,r,pos,x); 55 tree[node]=max(tree[node*2],tree[node*2+1]); 56 } 57 int query(int node,int l,int r,int ql,int qr) 58 { 59 if(ql<=l && r<=qr)return tree[node]; 60 int mid=(l+r)>>1; 61 int ans=-0x3f3f3f3f; 62 if(ql<mid)ans=max(query(node<<1,l,mid,ql,qr),ans); 63 if(mid<qr)ans=max(query(node<<1|1,mid,r,ql,qr),ans); 64 return ans; 65 } 66 int find(int x,int y) 67 { 68 int fa=top[x],fb=top[y],temp=0; 69 while(fa!=fb) 70 { 71 if(deep[fa]<deep[fb]) 72 { 73 swap(fa,fb); 74 swap(x,y); 75 } 76 if(id[fa]>id[x]+1)return -1; 77 temp=max(temp,query(1,1,pos+1,id[fa],id[x]+1)); 78 x=father[fa];fa=top[x]; 79 } 80 if(x==y)return temp; 81 if(deep[x]<deep[y])swap(x,y); 82 if(id[y]+1>id[x]+1)return -1; 83 return max(temp,query(1,1,pos+1,id[son[y]],id[x]+1)); 84 } 85 int main() 86 { 87 int t; 88 t=read(); 89 while(t--) 90 { 91 now=0; 92 memset(head,0,sizeof(head)); 93 memset(tree,0,sizeof(tree)); 94 n=read(); 95 for(int i=1;i<n;i++) 96 { 97 x[i]=read();y[i]=read();v[i]=read(); 98 add(x[i],y[i],v[i]); 99 add(y[i],x[i],v[i]); 100 } 101 deep[1]=0; 102 dfs(1,0); 103 dfs2(1,1,1); 104 for(int i=1;i<=n-1;i++) 105 { 106 int u=deep[x[i]]>deep[y[i]]?x[i]:y[i]; 107 update(1,1,pos+1,id[u],v[i]); 108 } 109 int xx,yy; 110 char ch[100]; 111 while(true) 112 { 113 scanf("%s",ch); 114 if(ch[0]=='D')break; 115 xx=read();yy=read(); 116 if(ch[0]=='Q') 117 { 118 printf("%d\n",find(xx,yy)); 119 } 120 else if(ch[0]=='C') 121 { 122 int u=deep[x[xx]]>deep[y[xx]]?x[xx]:y[xx]; 123 update(1,1,pos+1,id[u],yy); 124 } 125 else if(ch[0]=='D') 126 { 127 break; 128 } 129 } 130 } 131 return 0; 132 }