spoj 375 Query on a tree
题意:给一棵树,节点数不超过10000,有两个操作:1.询问a,b路径上最长的边长。2.把第a条边长度改为b.
p.s.人生中第一个树链剖分,尼玛debug了好久好久我擦。。。
分析:轻重边路径剖分,把点都映射到线段树上搞之。。。具体的东西等我刷一刷题之后一起写个总结吧o(╯□╰)o
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #define N 10010 6 #define lson l,m,n<<1 7 #define rson m+1,r,n<<1|1 8 using namespace std; 9 const int inf=1<<30; 10 struct Edge{ 11 int u,v,len,next; 12 Edge(){} 13 Edge(int _u,int _v,int _len,int _next):u(_u),v(_v),len(_len),next(_next){} 14 }edge[N<<1]; 15 int head[N],cnt; 16 int sz[N],son[N],top[N],hash[N],fa[N],dep[N],num; 17 int road[N][3]; 18 void init(){ 19 memset(head,-1,sizeof(head)); 20 cnt=num=0; 21 } 22 void add(int u,int v,int len){ 23 edge[cnt]=Edge(u,v,len,head[u]);head[u]=cnt++; 24 edge[cnt]=Edge(v,u,len,head[v]);head[v]=cnt++; 25 } 26 void dfs(int u,int d){ 27 sz[u]=1;son[u]=0;dep[u]=d; 28 for(int k=head[u];k!=-1;k=edge[k].next){ 29 int v=edge[k].v; 30 if(v==fa[u])continue; 31 fa[v]=u; 32 dfs(v,d+1); 33 sz[u]+=sz[v]; 34 if(sz[v]>sz[son[u]])son[u]=v; 35 } 36 } 37 void build_tree(int u,int pre){ 38 hash[u]=++num;top[u]=pre; 39 if(son[u])build_tree(son[u],pre); 40 for(int k=head[u];k!=-1;k=edge[k].next){ 41 int v=edge[k].v; 42 if(v!=fa[u]&&v!=son[u])build_tree(v,v); 43 } 44 } 45 struct segtree{ 46 int s[N<<2]; 47 void build(int l,int r,int n){ 48 s[n]=0; 49 if(l==r)return; 50 int m=(l+r)>>1; 51 build(lson); 52 build(rson); 53 } 54 void pushup(int n){ 55 s[n]=max(s[n<<1],s[n<<1|1]); 56 } 57 void update(int nn,int x,int l,int r,int n){ 58 if(l==r){ 59 s[n]=x; 60 return; 61 } 62 int m=(l+r)>>1; 63 if(nn<=m)update(nn,x,lson); 64 else update(nn,x,rson); 65 pushup(n); 66 } 67 int query(int ll,int rr,int l,int r,int n){ 68 if(ll==l&&rr==r)return s[n]; 69 int m=(l+r)>>1; 70 if(rr<=m)return query(ll,rr,lson); 71 else if(ll>m)return query(ll,rr,rson); 72 else return max(query(ll,m,lson),query(m+1,rr,rson)); 73 } 74 }seg; 75 int Query(int a,int b,int n){ 76 int ta=top[a],tb=top[b],ans=0; 77 while(ta!=tb){ 78 if(dep[ta]<dep[tb]){ 79 swap(a,b);swap(ta,tb); 80 } 81 ans=max(ans,seg.query(hash[ta],hash[a],1,n,1)); 82 a=fa[ta];ta=top[a]; 83 } 84 if(a==b)return ans; 85 if(dep[a]>dep[b])swap(a,b); 86 return max(ans,seg.query(hash[son[a]],hash[b],1,n,1)); 87 } 88 int main(){ 89 int t,a,b,n; 90 char op[10]; 91 scanf("%d",&t); 92 while(t--){ 93 scanf("%d",&n); 94 init(); 95 for(int i=1;i<n;i++){ 96 scanf("%d%d%d",&road[i][0],&road[i][1],&road[i][2]); 97 add(road[i][0],road[i][1],road[i][2]); 98 } 99 dfs(1,1); 100 build_tree(1,1); 101 seg.build(1,n,1); 102 for(int i=1;i<n;i++){ 103 if(dep[road[i][0]]>dep[road[i][1]])swap(road[i][0],road[i][1]); 104 seg.update(hash[road[i][1]],road[i][2],1,n,1); 105 } 106 while(scanf("%s",op)&&op[0]!='D'){ 107 scanf("%d%d",&a,&b); 108 if(op[0]=='Q'){ 109 int ans=Query(a,b,n); 110 printf("%d\n",ans); 111 }else if(op[0]=='C'){ 112 seg.update(hash[road[a][1]],b,1,n,1); 113 } 114 } 115 } 116 return 0; 117 }