题意:给个树和树上的权值,两个操作,Q u v,问u到v的边上的最大权值,C u v,将第u条边的权值改为v
思路:今天学了学树链剖分,这题是个检验模版的题目,理论我是解释不清楚的,自己在九野聚聚那学来的一份模版
#include <vector> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const int inf=0x3f3f3f3f; const ll INF=0x3f3f3f3f3f3f3f3fll; const int maxn=10010; int fa[maxn],siz[maxn],son[maxn],w[maxn],p[maxn],dep[maxn],fp[maxn]; //fa为父节点,siz为子节点中siz最大的,dep为深度,son为重儿子,w表示在线段树中的位置 int max1[maxn<<2]; int tree_id,n; vector<int>G[maxn]; void dfs1(int u,int ff,int deep){ son[u]=0;fa[u]=ff;siz[u]=1;dep[u]=deep; for(unsigned int i=0;i<G[u].size();i++){ int v=G[u][i]; if(v==ff) continue; dfs1(v,u,deep+1); siz[u]+=siz[v]; if(siz[v]>siz[son[u]]) son[u]=v; } } void dfs2(int u,int ff){ w[u]=++tree_id;p[u]=ff; if(son[u]) dfs2(son[u],ff); else return ; for(unsigned int i=0;i<G[u].size();i++){ int v=G[u][i]; if(v!=fa[u]&&v!=son[u]) dfs2(v,v); } } void update(int pos,int val,int le,int ri,int node){ if(le==ri){ max1[node]=val; return ; } int t=(le+ri)>>1; if(pos<=t) update(pos,val,le,t,node<<1); else update(pos,val,t+1,ri,node<<1|1); max1[node]=max(max1[node<<1],max1[node<<1|1]); } int query(int l,int r,int le,int ri,int node){ if(l<=le&&ri<=r) return max1[node]; int t=(le+ri)>>1,ans=0; if(l<=t) ans=max(ans,query(l,r,le,t,node<<1)); if(r>t) ans=max(ans,query(l,r,t+1,ri,node<<1|1)); return ans; } int getans(int u,int v){ int f1=p[u],f2=p[v],tmp=0; while(f1!=f2){ if(dep[f1]<dep[f2]){ swap(f1,f2); swap(u,v); } tmp=max(tmp,query(w[f1],w[u],1,n,1)); u=fa[f1];f1=p[u]; } if(u==v) return tmp; if(dep[u]>dep[v]) swap(u,v); return max(tmp,query(w[son[u]],w[v],1,n,1)); } int U[maxn],V[maxn],C[maxn]; int main(){ int T,u,v; char str[10]; scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i=0;i<maxn;i++) G[i].clear(); memset(son,0,sizeof(son));tree_id=0; for(int i=0;i<n-1;i++){ scanf("%d%d%d",&U[i],&V[i],&C[i]); G[U[i]].push_back(V[i]); G[V[i]].push_back(U[i]); } dfs1(1,1,0); dfs2(1,1); memset(max1,0,sizeof(max1)); for(int i=0;i<n-1;i++){ if(dep[U[i]]>dep[V[i]]) swap(U[i],V[i]); update(w[V[i]],C[i],1,n,1); } while(1){ scanf("%s",str); if(str[0]=='D') break; scanf("%d%d",&u,&v); if(str[0]=='C') update(w[V[u-1]],v,1,n,1); else printf("%d\n",getans(u,v)); } } return 0; }
时间: 2024-11-05 15:58:41