SPOJ375 Query on a tree经典入门题

  剖分边更新,线段树点更新区间求极值。学树链剖分感觉还是先做点更新的好,而不是边更新。其实最主要还用来维护的数据结构了,剖分基本上都成模板了。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 using namespace std;
  5 #define lson l,m,rt<<1
  6 #define rson m+1,r,rt<<1|1
  7 const int maxn = 10005;
  8 const int INF = 0x3f3f3f3f;
  9 int n;
 10 int siz[maxn],fa[maxn],son[maxn],dep[maxn];
 11 int top[maxn],tid[maxn],lable;
 12 int head[maxn],cnt;
 13 struct edge
 14 {
 15     int v,w,en,next;
 16 }e[maxn*2];
 17 int sum[maxn<<2];
 18 void init()
 19 {
 20     memset(head,-1,sizeof(head));
 21     cnt = lable = 0;
 22 }
 23 void add(int u,int v,int w)
 24 {
 25     e[cnt].v = v;
 26     e[cnt].w = w;
 27     e[cnt].next = head[u];
 28     head[u] = cnt++;
 29 }
 30 void find_heavy(int rt,int father,int depth)
 31 {
 32     fa[rt] = father;
 33     son[rt] = 0;
 34     siz[rt] = 1;
 35     dep[rt] = depth;
 36     int maxsize = 0;
 37     for(int i = head[rt];i!=-1;i = e[i].next)if(e[i].v!=father)
 38     {
 39         e[i].en = e[i^1].en = e[i].v;
 40         find_heavy(e[i].v,rt,depth+1);
 41         siz[rt]+=siz[e[i].v];
 42         if(siz[e[i].v]>maxsize)
 43             maxsize = siz[e[i].v],son[rt] = e[i].v;
 44     }
 45 }
 46 void pushup(int rt)
 47 {
 48     sum[rt] = max(sum[rt<<1],sum[rt<<1|1]);
 49 }
 50 void update(int pos ,int val,int l,int r,int rt)
 51 {
 52     if(l==r){
 53         sum[rt] = val;
 54         return;
 55     }
 56     int m = (l+r)>>1;
 57     if(pos<=m)update(pos,val,lson);
 58     else update(pos,val,rson);
 59     pushup(rt);
 60 }
 61 void connect(int rt,int anc)
 62 {
 63     tid[rt] = ++lable;
 64     top[rt] = anc;
 65     if(son[rt])connect(son[rt],anc);
 66     for(int  i= head[rt];i!=-1;i = e[i].next)
 67         if(e[i].v!=fa[rt]&&e[i].v!=son[rt])
 68             connect(e[i].v,e[i].v);
 69 }
 70 int query(int L,int R,int l,int r,int rt)
 71 {
 72     if(L<=l&&r<=R)return sum[rt];
 73     int m = (l+r)>>1,ret = -INF;
 74     if(L<=m)ret = max(ret,query(L,R,lson));
 75     if(m<R)ret = max(ret,query(L,R,rson));
 76     return ret;
 77 }
 78 int getmax(int x,int y)
 79 {
 80     int ans = -INF;
 81     while(top[x]!=top[y])
 82     {
 83         if(dep[top[x]]<dep[top[y]])swap(x,y);
 84         ans = max(ans,query(tid[top[x]],tid[x],1,n,1));
 85         x = fa[top[x]];
 86     }
 87     if(x==y)return ans;
 88     if(dep[x]>dep[y])swap(x,y);
 89     ans = max(ans,query(tid[son[x]],tid[y],1,n,1));
 90     return ans;
 91 }
 92 int main()
 93 {
 94   //  freopen("out.txt","r",stdin);
 95     int T;scanf("%d",&T);
 96     while(T--)
 97     {
 98         scanf("%d",&n);
 99         init();
100         for(int i = 1;i<n;++i)
101         {
102             int u,v,w;
103             scanf("%d%d%d",&u,&v,&w);
104             add(u,v,w);
105             add(v,u,w);
106         }
107         find_heavy(1,1,1);
108         connect(1,1);
109 
110         for(int i = 0;i<cnt;i+=2)update(tid[e[i].en],e[i].w,1,n,1);
111         update(1,0,1,n,1);
112         while(1)
113         {
114             char s[10];scanf("%s",s);
115             if(s[0]=='D')break;
116             int u,v;
117             scanf("%d%d",&u,&v);
118             if(s[0]=='Q')printf("%d\n",getmax(u,v));
119             else update(tid[e[u*2-1].en],v,1,n,1);
120         }
121     }
122     return 0;
123 }

 

posted on 2015-07-25 12:07  round_0  阅读(130)  评论(0编辑  收藏  举报

导航