POJ 3237.Tree -树链剖分-贴个板子备忘

Time Limit: 5000MS   Memory Limit: 131072K
Total Submissions: 12247   Accepted: 3151

Description

You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edges are numbered 1 through N − 1. Each edge is associated with a weight. Then you are to execute a series of instructions on the tree. The instructions can be one of the following forms:

CHANGE i v Change the weight of the ith edge to v
NEGATE a b Negate the weight of every edge on the path from a to b
QUERY a b Find the maximum weight of edges on the path from a to b

Input

The input contains multiple test cases. The first line of input contains an integer t (t ≤ 20), the number of test cases. Then follow the test cases.

Each test case is preceded by an empty line. The first nonempty line of its contains N (N ≤ 10,000). The next N − 1 lines each contains three integers ab and c, describing an edge connecting nodes a and b with weight c. The edges are numbered in the order they appear in the input. Below them are the instructions, each sticking to the specification above. A lines with the word “DONE” ends the test case.

Output

For each “QUERY” instruction, output the result on a separate line.

Sample Input

1

3
1 2 1
2 3 2
QUERY 1 2
CHANGE 1 3
QUERY 1 2
DONE

Sample Output

1
3

Source

 
 
 
 
 

题意就是: 有T组数据 ,给你n个点的树,有三种操作:

 1.CHANGE i v :将第i条边的值改为v   

 2.NEGATE a b :将a点到b点路径上的边权取反      

3.QUERY a b :查询a点到b点路径上最大的边权值,

由于有取反操作,记录最大和最小值 然后取反并交换就可以,用线段树来维护。

一开始打死都不想用结构体版的,最后发现结构体版的好像写起来简洁一些,真香警告。。。

代码:

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<bitset>
  6 #include<cassert>
  7 #include<cctype>
  8 #include<cmath>
  9 #include<cstdlib>
 10 #include<ctime>
 11 #include<deque>
 12 #include<iomanip>
 13 #include<list>
 14 #include<map>
 15 #include<queue>
 16 #include<set>
 17 #include<stack>
 18 #include<vector>
 19 using namespace std;
 20 typedef long long ll;
 21 
 22 const double PI=acos(-1.0);
 23 const double eps=1e-6;
 24 const ll mod=1e9+7;
 25 const int inf=0x3f3f3f3f;
 26 const int maxn=2e5+10;
 27 const int maxm=100+10;
 28 #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
 29 #define lson t<<1,l,mid
 30 #define rson t<<1|1,mid+1,r
 31 
 32 
 33 
 34 int eg[maxn][3];
 35 int head[maxn],cnt;
 36 
 37 struct Edge{
 38     int to,next;
 39 }edge[maxn<<1];
 40 
 41 void add(int u,int v)
 42 {
 43     edge[cnt].to=v;
 44     edge[cnt].next=head[u];
 45     head[u]=cnt++;
 46 }
 47 
 48 int num;
 49 int val[maxn],siz[maxn],dep[maxn],son[maxn];
 50 int top[maxn],tid[maxn],pos[maxn],fa[maxn];
 51 
 52 void init()
 53 {
 54     memset(head,-1,sizeof(head));
 55     memset(son,-1,sizeof(son));
 56     cnt=num=0;
 57 }
 58 
 59 ///树链剖分部分
 60 void dfs1(int u,int father,int d)
 61 {
 62     dep[u]=d;
 63     fa[u]=father;
 64     siz[u]=1;
 65     for(int i=head[u];~i;i=edge[i].next)
 66     {
 67         int v=edge[i].to;
 68         if(v!=father)
 69         {
 70             dfs1(v,u,d+1);
 71             siz[u]+=siz[v];
 72             if(son[u]==-1||siz[v]>siz[son[u]])
 73                 son[u]=v;
 74         }
 75     }
 76 }
 77 
 78 void dfs2(int u,int tp)
 79 {
 80     top[u]=tp;
 81     tid[u]=++num;
 82     pos[tid[u]]=u;
 83     if(son[u]==-1) return ;
 84     dfs2(son[u],tp);
 85     for(int i=head[u];~i;i=edge[i].next)
 86     {
 87         int v=edge[i].to;
 88         if(v!=son[u]&&v!=fa[u])
 89             dfs2(v,v);
 90     }
 91 }
 92 
 93 ///线段树部分
 94 struct Node{
 95     int l,r,mx,mn,lazy;
 96 }node[maxn<<2];
 97 
 98 void Swap(int &x,int &y){int t=x;x=-y;y=-t;}
 99 
100 void pushup(int t)
101 {
102     node[t].mx=max(node[t<<1].mx,node[t<<1|1].mx);
103     node[t].mn=min(node[t<<1].mn,node[t<<1|1].mn);
104 }
105 
106 void pushdown(int t)
107 {
108     if(node[t].lazy)
109     {
110         int tmp=node[t].lazy;
111         node[t<<1].lazy+=tmp;
112         node[t<<1|1].lazy+=tmp;
113         ///注意这里,两个子区间是否取反是依靠当前区间的懒惰标记判断的
114         if(tmp&1)
115         {
116             Swap(node[t<<1].mx,node[t<<1].mn);
117             Swap(node[t<<1|1].mx,node[t<<1|1].mn);
118         }
119         node[t].lazy=0;
120     }
121 }
122 
123 void build(int t,int l,int r)
124 {
125     node[t].l=l;
126     node[t].r=r;
127     node[t].lazy=0;
128     if(l==r)
129     {
130         node[t].mx=node[t].mn=0;
131         return ;
132     }
133 
134     int mid=(l+r)>>1;
135     build(lson);
136     build(rson);
137     pushup(t);
138 }
139 
140 void update(int t,int ind,int v)
141 {
142     if(node[t].l==node[t].r&&node[t].l==ind)
143     {
144         node[t].mx=v;
145         node[t].mn=v;
146         node[t].lazy=0;
147         return ;
148     }
149 
150     pushdown(t);
151     int mid=(node[t].l+node[t].r)>>1;
152     if(ind<=mid) update(t<<1,ind,v);
153     else         update(t<<1|1,ind,v);
154     pushup(t);
155 }
156 
157 void Negate(int t,int l,int r)
158 {
159     if(node[t].l>=l&&node[t].r<=r)
160     {
161         node[t].lazy++;
162         Swap(node[t].mx,node[t].mn);//这里要马上取反
163         return ;
164     }
165 
166     pushdown(t);
167     int mid=(node[t].l+node[t].r)>>1;
168     if(l<=mid) Negate(t<<1,l,r);
169     if(r> mid) Negate(t<<1|1,l,r);
170     pushup(t);
171 }
172 
173 int query(int t,int l,int r)
174 {
175     if(node[t].l>=l&&node[t].r<=r)
176     {
177         return node[t].mx;
178     }
179 
180     pushdown(t);
181     int ret=-inf;
182     int mid=(node[t].l+node[t].r)>>1;
183     if(l<=mid) ret=max(ret,query(t<<1,l,r));
184     if(r> mid) ret=max(ret,query(t<<1|1,l,r));
185     pushup(t);
186     return ret;
187 }
188 
189 int solveMax(int x,int y)
190 {
191     int ret=-inf;
192     while(top[x]!=top[y])
193     {
194         if(dep[top[x]]<dep[top[y]]) swap(x,y);
195         ret=max(ret,query(1,tid[top[x]],tid[x]));
196         x=fa[top[x]];
197     }
198 
199     if(x==y) return ret;
200     if(dep[x]>dep[y]) swap(x,y);
201     return max(ret,query(1,tid[son[x]],tid[y]));
202 }
203 
204 void change(int x,int y)
205 {
206     while(top[x]!=top[y])
207     {
208         if(dep[top[x]]<dep[top[y]]) swap(x,y);
209         Negate(1,tid[top[x]],tid[x]);
210         x=fa[top[x]];
211     }
212 
213     if(x==y) return ;
214     if(dep[x]>dep[y]) swap(x,y);
215     Negate(1,tid[son[x]],tid[y]);
216 }
217 
218 int main()
219 {
220     char ope[10];
221     int T,n;scanf("%d",&T);
222     while(T--)
223     {
224         scanf("%d",&n);
225         init();
226         for(int i=1;i<n;i++)
227         {
228             scanf("%d%d%d",&eg[i][0],&eg[i][1],&eg[i][2]);
229             add(eg[i][0],eg[i][1]);
230             add(eg[i][1],eg[i][0]);
231         }
232         dfs1(1,0,0);
233         dfs2(1,1);
234         build(1,1,n);
235         for(int i=1;i<n;i++)
236         {
237             if(dep[eg[i][0]]<dep[eg[i][1]]) swap(eg[i][0],eg[i][1]);
238             update(1,tid[eg[i][0]],eg[i][2]);
239         }
240         int a,b;
241         while(scanf("%s",ope)&&ope[0]!='D')
242         {
243             scanf("%d%d",&a,&b);
244             if(ope[0]=='Q')
245             {
246                 printf("%d\n",solveMax(a,b));
247             }
248             if(ope[0]=='C')
249             {
250                 update(1,tid[eg[a][0]],b);
251             }
252             if(ope[0]=='N')
253             {
254                 change(a,b);
255             }
256         }
257     }
258 }

猜你喜欢

转载自www.cnblogs.com/ZERO-/p/9670796.html
今日推荐