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 }

 

posted @ 2013-02-08 10:50  silver__bullet  阅读(165)  评论(0编辑  收藏  举报