P1424 - [POJ3237]树的维护

Description

给你由N个结点组成的树。树的节点被编号为1到N,边被编号为1到N-1。每一条边有一个权值。然后你要在树上执行一系列指令。指令可以是如下三种之一:
CHANGE i v:将第i条边的权值改成v。
NEGATE a b:将点a到点b路径上所有边的权值变成其相反数。
QUERY a b:找出点a到点b路径上各边的最大权值。

Input

第一行有一个整数N(N<=10000)。
接下来N-1行每行有三个整数a,b,c,代表点a和点b之间有一条权值为c的边。这些边按照其编号从小到大给出。
接下来是若干条指令(不超过10^5条),都按照上面所说的格式。
最后一行是"DONE".

Output

对每个“QUERY”指令,输出一行,即路径上各边的最大权值。

Sample Input

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

Sample Output

1
3

Hint

Source

POJ 3237 Tree
树链剖分, 动态树, LCA

线段树,TMD调了我一个晚上+半个上午,最后才知道是因为lazy标记没有下放,woc

  1 #define ls o*2
  2 #define rs o*2+1
  3
  4 #define inf 1999999999
  5 #include<algorithm>
  6 #include<iostream>
  7 #include<iomanip>
  8 #include<cstring>
  9 #include<cstdlib>
 10 #include<cstdio>
 11 #include<queue>
 12 #include<ctime>
 13 #include<cmath>
 14 #include<stack>
 15 #include<map>
 16 #include<set>
 17 using namespace std;
 18 const int N=10010,M=N-1;
 19 struct E{
 20     int to,net,w;
 21     int fr;
 22 }e[M*2];
 23 struct TREE{
 24     int bj,Max,Min;
 25     TREE(){
 26     bj=1;
 27     }
 28 }tr[N*4];
 29 int head[N],n,num_e;
 30 void add(int x,int y,int w) {
 31     e[++num_e].to=y;e[num_e].net=head[x];head[x]=num_e;e[num_e].w=w;e[num_e].fr=x;
 32 }
 33 void down(int);
 34 int dep[N],top[N],son[N],tid[N],pos[N],fa[N],siz[N],val[N],idx;
 35 int W[N],len[N*4];
 36 int B[M*2];
 37 void dfs1(int x,int fu) {
 38     siz[x]=1;
 39     dep[x]=dep[fu]+1;//
 40     son[x]=0;
 41     fa[x]=fu;//  meinong
 42     for(int i=head[x];i;i=e[i].net) {
 43     int to=e[i].to;
 44         if(to!=fu) {
 45         val[to]=e[i].w;
 46         dfs1(to,x);
 47         siz[x] += siz[to];//  这一步竟然忘了!!!!
 48         if(siz[to]>siz[son[x]]) son[x]=to;
 49 //        printf("x=%d son=%d",x,son[x]);P
 50         }
 51     }
 52 }
 53 void dfs2(int x,int tp) {
 54     tid[x]=++idx;
 55     pos[idx]=x;
 56     top[x]=tp;
 57     W[idx]=val[x];//
 58     if(son[x]==0) return;
 59     dfs2(son[x],tp);
 60     for(int i=head[x];i;i=e[i].net)
 61     if(e[i].to!=son[x]&&dep[e[i].to]>dep[x]) {
 62         dfs2(e[i].to,e[i].to);
 63     }
 64 }
 65 void build(int o,int L,int R) {
 66     if(L==R) {
 67     if(L==1) tr[o].Max=-inf,tr[o].Min=inf;
 68      else
 69       tr[o].Max=W[L],tr[o].Min=W[L];
 70     return;
 71     }
 72     int mid=(L+R)>>1;
 73     build(ls,L,mid);
 74     build(rs,mid+1,R);
 75     tr[o].Max=max(tr[ls].Max,tr[rs].Max);
 76     tr[o].Min=min(tr[ls].Min,tr[rs].Min);
 77 }
 78 void Update(int o,int L,int R,int p,int x) {
 79     if(L!=R) down(o);
 80     if(p==L&&R==p) {
 81     tr[o].Max=x;tr[o].Min=x;
 82     return;
 83     }
 84     int mid=(L+R)>>1;
 85     if(p<=mid) Update(ls,L,mid,p,x);
 86     else Update(rs,mid+1,R,p,x);
 87     tr[o].Max=max(tr[ls].Max,tr[rs].Max);
 88     tr[o].Min=min(tr[ls].Min,tr[rs].Min);
 89 }
 90 void GG(int,int,int,int,int);
 91 //  GG Update()
 92 void solveG(int x,int y) {
 93     while(top[x]!=top[y]) {
 94         if(dep[top[x]]>dep[top[y]]) swap(x,y);
 95         GG(1,1,n,tid[top[y]],tid[y]);
 96         y=fa[top[y]];
 97     }
 98     if(dep[x]>dep[y]) swap(x,y);
 99     if(x==y) return;//  y
100     GG(1,1,n,tid[x]+1,tid[y]);
101 }
102 void down(int o) {
103     int mi;
104     int k=tr[o].bj;
105     if(tr[o].bj==1) return;
106     mi=tr[ls].Min;tr[ls].Min=k*tr[ls].Max,tr[ls].Max=mi*k;//mi
107     mi=tr[rs].Min;tr[rs].Min=k*tr[rs].Max,tr[rs].Max=k*mi;
108     tr[o].bj=1;//复原 //  tr[o].bj==1
109     tr[ls].bj*=-1;
110     tr[rs].bj*=-1;//
111     return;
112 }
113 int querymax(int o,int L,int R,int l,int r) {
114     if(L!=R) down(o);
115     if(l<=L&&R<=r) {
116     return tr[o].Max;
117     }
118     int Max=-inf;
119     int mid=(L+R)>>1;
120     if(l<=mid) Max=max(Max,querymax(ls,L,mid,l,r));
121     if(r>mid) Max=max(Max,querymax(rs,mid+1,R,l,r));
122     return Max;
123 }
124
125 void GG(int o,int L,int R,int l,int r) {
126     if(L!=R) down(o);
127     if(l<=L&&R<=r) {
128         int mi=tr[o].Min,ma=tr[o].Max;
129         //    tr[o].bj*=-1;
130         tr[o].bj=-1;
131         tr[o].Min=-ma;tr[o].Max=-mi;
132         return;
133     }
134     int mid=(L+R)>>1;
135     if(l<=mid) GG(ls,L,mid,l,r);
136     if(r>mid) GG(rs,mid+1,R,l,r);
137     tr[o].Max=max(tr[ls].Max,tr[rs].Max);
138     tr[o].Min=min(tr[ls].Min,tr[rs].Min);
139 }
140 int solvemax(int x,int y) {
141     int Max=-inf;
142
143     while(top[x]!=top[y]) {
144     if(dep[top[x]]>dep[top[y]]) swap(x,y);
145     Max=max(Max,querymax(1,1,n,tid[top[y]],tid[y]));
146         y=fa[top[y]];
147     }
148     if(dep[x]>dep[y]) swap(x,y);
149     if(x==y) return Max;
150     Max=max(Max,querymax(1,1,n,tid[x]+1,tid[y]));
151     return Max;
152 }
153 int main() {
154
155     cin>>n;int i;
156     for(i=1;i<n;i++) {
157         int x,y,w;scanf("%d%d%d",&x,&y,&w);
158         add(x,y,w);
159         B[i]=num_e;
160         add(y,x,w);
161         }
162         dfs1(1,0);
163         dfs2(1,1);
164         for(i=1;i<n;i++) {
165              int x=e[B[i]].fr,y=e[B[i]].to;
166              if(dep[x]<dep[y]) B[i]=y;
167              else B[i]=x;
168         }
169         build(1,1,n);
170         string s;
171         while(1) {
172         cin>>s;
173         int a,b;scanf("%d%d",&a,&b);
174         if(s[0]=='D') break;
175         else if(s[0]=='C') {
176             a=B[a];
177             Update(1,1,n,tid[a],b);
178         }
179         else if(s[0]=='N') {
180             solveG(a,b);
181            }
182         else printf("%d\n",solvemax(a,b));
183     }
184     return 0;
185 }

View Code

转载于:https://www.cnblogs.com/ypz999/p/6621860.html

POJ3237 树的维护相关推荐

  1. 牛客 - 求函数(线段树+区间合并/线段树+矩阵维护)

    题目链接:点击查看 题目大意:现在有 n 个函数,每个函数都是诸如 f( x ) = k * x + b 的形式,只是每个函数的 k 和 b 都是相互独立的,现在给出两个操作: 1 pos k b:将 ...

  2. 【BZOJ2653】middle,主席树(非权值线段树)维护序列和信息+二分答案

    传送门 写在前面:虽然这是一道我再也不想写的题目,但很好很有价值 思路: cxlove大神: 要求中位数最大,首先二分中位数,然后判断可行不可行. 判断X可行不可行,对于区间内的数,凡是>=X的 ...

  3. 买礼物(线段树+set维护)

    原题 题意:有两种操作 1 x 表示删去x位置的数 2 l r 表示查询l到r区间是否存在两个数相同. 题解: w[i]表示i前面与a[i]相同的数a[j]且下标最大的j.w[i]表示i前面与a[i] ...

  4. 时空旅行[线段树分治][维护凸壳]

    文章目录 前言 题目 思路 代码 前言 肝了一上午-这是我才学线段树分治的例题-真舒服 题目 温馨提示:首先在UOJ做,LOJ挖数据,BZOJ终极评测... UOJ198 二手剽- 思路 为什么不能用 ...

  5. HDU 5454 Excited Database 线段树的维护

    传送门:HDU5454 Excited Database Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 65535/102400 K ...

  6. 2019牛客暑期多校训练营(第一场场)_I题Points Division(线段树+DP维护区间最大值)

    题目链接: https://ac.nowcoder.com/acm/contest/881/I 题意: 给你n个点,每个点的坐标为(xi,yi),有两个权值ai,bi. 现在要你将它分成A,B两部分, ...

  7. 树链剖分概念及模板 + 例题 [POJ3237 tree + 软件包管理器]

    文章目录 概念 模板 例题1:软件包管理器 题目 题解 代码实现 例题2:POJ3237 tree 题目 题解 代码实现 概念 树链剖分主要是用于解决以下这两个问题. 1.更改树上点x到点y的最短路径 ...

  8. [HNOIAHOI2018] 转盘(线段树维护单调栈)

    problem 洛谷链接 solution 结论:最优方案中一定有一种是全程不停的. 断环成链,接一个 [1,n][1,n][1,n] 在后面形成 2n2n2n 的序列,同时将时间戳逆过来. 转化成: ...

  9. [NOI2018] 归程(线段树维护并查集的可持久化/kruskal重构树,倍增+dijkstra最短路)

    [NOI2018] 归程 description solution1 code1 solution2 code description 题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要 ...

最新文章

  1. LeetCode 462 Minimum Moves to Equal Array Elements II
  2. php7连接mongodb,批量添加数据
  3. 操作系统学习笔记-2.1.3进程控制
  4. 【算法分析与设计】排序算法的时间复杂度与O(NlogN)
  5. 扩散(洛谷-P1661)
  6. mysql 连接池 数量_mysql合理配置连接池数量
  7. 一致性Hash简单介绍和使用
  8. java数字类型_Java数据类型
  9. 2014年3月计算机四级网络工程师考试试题及答案,某年3月计算机等级考试四级网络工程师笔试试题...
  10. 使用 Hasor 从数据库查询显示到页面上
  11. 一封程序员的苦逼辞职信
  12. JS魔法堂:元素克隆、剪切技术研究
  13. webservice接口开发经历
  14. SpringBoot整合腾讯云短信服务实现发送短信功能(一篇就够了)
  15. gogo系统更新无服务器,gogo云服务器
  16. PS和AE结合设计的进度条,有图有视频(秒懂)
  17. 2020年9月指数定期审核与调整 | TokenInsight
  18. css小tips -- figcaption标签
  19. CES2018,三星为何将MicroLED应用于电视而非手机?
  20. Python机器学习基础教程(1)Irises(鸢尾花)分类之新手上路

热门文章

  1. 快钱如何快-企业级效率提升实践
  2. 关于 angularjs 的小结
  3. Drupal 关于节点(nodes)的理解
  4. 【资源分享】CS起源 V34.4044(经典版本)
  5. CGI,FastCGI,PHP-CGI,PHP-FPM
  6. 源代码管理工具优缺点
  7. 【CSS3】CSS——链接
  8. Python进阶(5)_进程与线程之协程、I/O模型
  9. (转)Java中equals和==、hashcode的区别
  10. XCTF_Web_新手练习区:disabled_button