码迷,mamicode.com
首页 > 其他好文 > 详细

POJ3237 Tree

时间:2015-07-28 18:14:11      阅读:107      评论:0      收藏:0      [点我收藏+]

标签:

树链剖分边更新,线段树区间更新(取相反数)+单点更新,区间查询最大值,区间取相反数的操作可以维护两个值mmax和mmin,当取反时最大最小值取反互换

  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 = 100005;
  8 const int INF = 0x3f3f3f3f;
  9 int siz[maxn],son[maxn],dep[maxn],tid[maxn],top[maxn],fa[maxn];
 10 int head[maxn],cnt,lable;
 11 int n,m;
 12 struct edge
 13 {
 14     int v,next,w,en;
 15 }e[maxn*2];
 16 int mmax[maxn<<2],mmin[maxn<<2],lazy[maxn<<2];
 17 void init()
 18 {
 19     memset(head,-1,sizeof(head));
 20     cnt = lable = 0;
 21 }
 22 void add(int u,int v,int w)
 23 {
 24     e[cnt].v = v;
 25     e[cnt].w = w;
 26     e[cnt].next = head[u];
 27     head[u] = cnt++;
 28 }
 29 void find_heavy(int rt,int father,int depth)
 30 {
 31     int maxsize = 0;
 32     fa[rt] = father;
 33     son[rt] = 0;
 34     siz[rt] = 1;
 35     dep[rt] = depth;
 36     for(int i = head[rt];i!=-1;i = e[i].next)if(e[i].v!=father){
 37         e[i].en = e[i^1].en = e[i].v;
 38         find_heavy(e[i].v,rt,depth+1);
 39         siz[rt]+=siz[e[i].v];
 40         if(siz[e[i].v]>maxsize){
 41             son[rt] = e[i].v,maxsize = siz[e[i].v];
 42         }
 43     }
 44 }
 45 void connect(int rt,int anc)
 46 {
 47     tid[rt] = ++lable;
 48     top[rt] = anc;
 49     if(son[rt])connect(son[rt],anc);
 50     for(int i = head[rt];i!=-1;i=e[i].next)
 51         if(e[i].v!=fa[rt]&&e[i].v!=son[rt])
 52             connect(e[i].v,e[i].v);
 53 }
 54 void pushup(int rt)
 55 {
 56     mmax[rt] = max(mmax[rt<<1],mmax[rt<<1|1]);
 57     mmin[rt] = min(mmin[rt<<1],mmin[rt<<1|1]);
 58 }
 59 void pushdown(int rt)
 60 {
 61     if(lazy[rt]==-1)
 62     {
 63         int t = mmax[rt<<1];
 64         mmax[rt<<1] = -mmin[rt<<1];
 65         mmin[rt<<1] = -t;
 66         t = mmax[rt<<1|1];
 67         mmax[rt<<1|1] = -mmin[rt<<1|1];
 68         mmin[rt<<1|1] = -t;
 69         if(lazy[rt<<1]==0)lazy[rt<<1] = -1;
 70         else lazy[rt<<1]*=-1;
 71         if(lazy[rt<<1|1]==0)lazy[rt<<1|1] = -1;
 72         else lazy[rt<<1|1]*=-1;
 73         lazy[rt] = 0;
 74     }
 75     else lazy[rt] = 0;
 76 }
 77 int query(int L,int R,int l,int r,int rt)
 78 {
 79     if(L<=l&&r<=R)return mmax[rt];
 80     pushdown(rt);
 81     int m = (l+r)>>1,ret = -INF;
 82     if(L<=m)ret = max(ret,query(L,R,lson));
 83     if(m<R)ret = max(ret,query(L,R,rson));
 84     return ret;
 85 }
 86 int getmmax(int x,int y)
 87 {
 88     int ans = -INF;
 89     while(top[x]!=top[y])
 90     {
 91         if(dep[top[x]]<dep[top[y]])swap(x,y);
 92         ans = max(ans,query(tid[top[x]],tid[x],1,n,1));
 93         x = fa[top[x]];
 94     }
 95     if(dep[x]>dep[y])swap(x,y);
 96     if(x==y)return ans;
 97     ans = max(ans,query(tid[son[x]],tid[y],1,n,1));
 98     return ans;
 99 }
100 void update(int pos,int val,int l,int r,int rt)
101 {
102     if(l==r){
103         mmax[rt] = val;
104         mmin[rt] = val;
105         return;
106     }
107     pushdown(rt);
108     int m = (l+r)>>1;
109     if(pos<=m)update(pos,val,lson);
110     else update(pos,val,rson);
111     pushup(rt);
112 }
113 void UPDATE(int L,int R,int l,int r,int rt)
114 {
115     if(L<=l&&r<=R){
116         int t = mmax[rt];
117         mmax[rt] = -mmin[rt];
118         mmin[rt] = -t;
119         if(lazy[rt]==0)lazy[rt] = -1;
120         else lazy[rt]*=-1;
121         return;
122     }
123     pushdown(rt);
124     int m = (l+r)>>1;
125     if(L<=m)UPDATE(L,R,lson);
126     if(m<R)UPDATE(L,R,rson);
127     pushup(rt);
128 }
129 void change(int x,int y)
130 {
131     while(top[x]!=top[y])
132     {
133         if(dep[top[x]]<dep[top[y]])swap(x,y);
134         UPDATE(tid[top[x]],tid[x],1,n,1);
135         x = fa[top[x]];
136     }
137     if(dep[x]>dep[y])swap(x,y);
138     if(x!=y)UPDATE(tid[son[x]],tid[y],1,n,1);
139 }
140 int main()
141 {
142     int T;scanf("%d",&T);
143     while(T--)
144     {
145         init();
146         scanf("%d",&n);
147         for(int i = 1;i<n;++i){
148             int u,v,w;scanf("%d%d%d",&u,&v,&w);
149             add(u,v,w);add(v,u,w);
150         }
151         find_heavy(1,1,1);
152         connect(1,1);
153         for(int i = 0;i<cnt;i+=2)update(tid[e[i].en],e[i].w,1,n,1);
154         while(1)
155         {
156             char s[10];int a,b;
157             scanf("%s",s);
158             if(s[0]==D)break;
159             scanf("%d%d",&a,&b);
160             if(s[0]==Q)printf("%d\n",getmmax(a,b));
161             else if(s[0]==C)update(tid[e[2*a-1].en],b,1,n,1);
162             else change(a,b);
163         }
164     }
165     return 0;
166 }

 

POJ3237 Tree

标签:

原文地址:http://www.cnblogs.com/GJKACAC/p/4683287.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!