AmazingCounters.com

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 }

 

posted @ 2015-03-15 17:37  philippica  阅读(129)  评论(0编辑  收藏  举报