POJ3237 树的维护
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 树的维护相关推荐
- 牛客 - 求函数(线段树+区间合并/线段树+矩阵维护)
题目链接:点击查看 题目大意:现在有 n 个函数,每个函数都是诸如 f( x ) = k * x + b 的形式,只是每个函数的 k 和 b 都是相互独立的,现在给出两个操作: 1 pos k b:将 ...
- 【BZOJ2653】middle,主席树(非权值线段树)维护序列和信息+二分答案
传送门 写在前面:虽然这是一道我再也不想写的题目,但很好很有价值 思路: cxlove大神: 要求中位数最大,首先二分中位数,然后判断可行不可行. 判断X可行不可行,对于区间内的数,凡是>=X的 ...
- 买礼物(线段树+set维护)
原题 题意:有两种操作 1 x 表示删去x位置的数 2 l r 表示查询l到r区间是否存在两个数相同. 题解: w[i]表示i前面与a[i]相同的数a[j]且下标最大的j.w[i]表示i前面与a[i] ...
- 时空旅行[线段树分治][维护凸壳]
文章目录 前言 题目 思路 代码 前言 肝了一上午-这是我才学线段树分治的例题-真舒服 题目 温馨提示:首先在UOJ做,LOJ挖数据,BZOJ终极评测... UOJ198 二手剽- 思路 为什么不能用 ...
- HDU 5454 Excited Database 线段树的维护
传送门:HDU5454 Excited Database Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 65535/102400 K ...
- 2019牛客暑期多校训练营(第一场场)_I题Points Division(线段树+DP维护区间最大值)
题目链接: https://ac.nowcoder.com/acm/contest/881/I 题意: 给你n个点,每个点的坐标为(xi,yi),有两个权值ai,bi. 现在要你将它分成A,B两部分, ...
- 树链剖分概念及模板 + 例题 [POJ3237 tree + 软件包管理器]
文章目录 概念 模板 例题1:软件包管理器 题目 题解 代码实现 例题2:POJ3237 tree 题目 题解 代码实现 概念 树链剖分主要是用于解决以下这两个问题. 1.更改树上点x到点y的最短路径 ...
- [HNOIAHOI2018] 转盘(线段树维护单调栈)
problem 洛谷链接 solution 结论:最优方案中一定有一种是全程不停的. 断环成链,接一个 [1,n][1,n][1,n] 在后面形成 2n2n2n 的序列,同时将时间戳逆过来. 转化成: ...
- [NOI2018] 归程(线段树维护并查集的可持久化/kruskal重构树,倍增+dijkstra最短路)
[NOI2018] 归程 description solution1 code1 solution2 code description 题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要 ...
最新文章
- LeetCode 462 Minimum Moves to Equal Array Elements II
- php7连接mongodb,批量添加数据
- 操作系统学习笔记-2.1.3进程控制
- 【算法分析与设计】排序算法的时间复杂度与O(NlogN)
- 扩散(洛谷-P1661)
- mysql 连接池 数量_mysql合理配置连接池数量
- 一致性Hash简单介绍和使用
- java数字类型_Java数据类型
- 2014年3月计算机四级网络工程师考试试题及答案,某年3月计算机等级考试四级网络工程师笔试试题...
- 使用 Hasor 从数据库查询显示到页面上
- 一封程序员的苦逼辞职信
- JS魔法堂:元素克隆、剪切技术研究
- webservice接口开发经历
- SpringBoot整合腾讯云短信服务实现发送短信功能(一篇就够了)
- gogo系统更新无服务器,gogo云服务器
- PS和AE结合设计的进度条,有图有视频(秒懂)
- 2020年9月指数定期审核与调整 | TokenInsight
- css小tips -- figcaption标签
- CES2018,三星为何将MicroLED应用于电视而非手机?
- Python机器学习基础教程(1)Irises(鸢尾花)分类之新手上路