HDU 3237 Tree(树链剖分)(线段树区间取反,最大值)
| Time Limit: 5000MS | Memory Limit: 131072K | |
| Total Submissions: 9123 | Accepted: 2411 |
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 a, b 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
【分析】题意很好理解,唯一的难点就是将某一区间内的数变成相反数,需要用到懒惰标记。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <time.h>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#define met(a,b) memset(a,b,sizeof a)
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
typedef long long ll;
const int N=2e5+;
const int M=N*N+;
int dep[N],siz[N],fa[N],id[N],son[N],val[N],top[N]; //top 最近的重链父节点
int num,s,m,n,q;
int sum[N*],tre[*N];
int maxn[N],minn[N],lazy[N];
vector<int> v[N];
struct tree {
int x,y,val;
void read() {
scanf("%d%d%d",&x,&y,&val);
}
} e[N];
void dfs1(int u, int f, int d) {
dep[u] = d;
siz[u] = ;
son[u] = ;
fa[u] = f;
for (int i = ; i < v[u].size(); i++) {
int ff = v[u][i];
if (ff == f) continue;
dfs1(ff, u, d + );
siz[u] += siz[ff];
if (siz[son[u]] < siz[ff])
son[u] = ff;
}
}
void dfs2(int u, int tp) {
top[u] = tp;
id[u] = ++num;
if (son[u]) dfs2(son[u], tp);
for (int i = ; i < v[u].size(); i++) {
int ff = v[u][i];
if (ff == fa[u] || ff == son[u]) continue;
dfs2(ff, ff);
}
}
void ChangeVal(int rt) {
int tmp=maxn[rt];
maxn[rt]=-minn[rt];
minn[rt]=-tmp;
}
void Push_up(int rt) {
maxn[rt]=max(maxn[*rt],maxn[*rt+]);
minn[rt]=min(minn[*rt],minn[*rt+]);
}
void Push_down(int rt) {
if(lazy[rt]) {
lazy[rt]^=;
lazy[*rt]^=;
ChangeVal(rt*);
lazy[*rt+]^=;
ChangeVal(*rt+);
}
}
void change(int t,int l,int r,int x,int v){
if(l==r) maxn[t]=minn[t]=v;
else{
Push_down(t);
int mid=(l+r)>>;
if(x<=mid) change(t*,l,mid,x,v);
else change(t*+,mid+,r,x,v);
Push_up(t);
}
}
void Build(int l,int r,int rt) {
if(l==r) {
maxn[rt]=minn[rt]=val[l];
return;
}
int m=(l+r)>>;
Build(lson);
Build(rson);
Push_up(rt);
//printf("rt=%d sum[rt]=%d\n",rt,sum[rt]);
} void Update(int L,int R,int l,int r,int rt) {
if(l>=L&&r<=R) {
lazy[rt]^=;
ChangeVal(rt);
return;
}
Push_down(rt);
int m=(r+l)>>;
if(L<=m)Update(L,R,lson);
if(R>m) Update(L,R,rson);
Push_up(rt);
} int Query(int L,int R,int l,int r,int rt) {
if(L<=l&&r<=R)return maxn[rt];
Push_down(rt);
int m=(l+r)>>;
if(R<=m)return Query(L,R,lson);
else if(L>m)return Query(L,R,rson);
else return max(Query(L,m,lson),Query(m+,R,rson));
} void solve(int u, int v) {
int tp1 = top[u], tp2 = top[v];
int ans = ;
while (tp1 != tp2) {
if (dep[tp1] < dep[tp2]) {
swap(tp1, tp2);
swap(u, v);
}
Update(id[tp1],id[u],,n,);
u = fa[tp1];
tp1 = top[u];
}
if (u == v) return;
if (dep[u] > dep[v]) swap(u, v);
Update(id[son[u]],id[v],,n,);
return;
}
int Yougth(int u,int v) {
int tp1 = top[u], tp2 = top[v];
int ans=-;
while (tp1 != tp2) {
if (dep[tp1] < dep[tp2]) {
swap(tp1, tp2);
swap(u, v);
}
ans = max(Query(id[tp1], id[u],,n,),ans);
u = fa[tp1];
tp1 = top[u];
}
if (u == v) return ans;
if (dep[u] > dep[v]) swap(u, v);
ans = max(Query(id[son[u]], id[v],,n,),ans);
return ans;
}
void Clear(int n) {
for(int i=; i<=n; i++)
v[i].clear();
met(son,);met(maxn,);met(minn,);
met(lazy,);
}
int main() {
int t;
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
Clear(n);
int u,vv,w;
for(int i=; i<n; i++) {
e[i].read();
v[e[i].x].push_back(e[i].y);
v[e[i].y].push_back(e[i].x);
}
num = ;
dfs1(,,);
dfs2(,);
for (int i = ; i < n; i++) {
if (dep[e[i].x] < dep[e[i].y]) swap(e[i].x, e[i].y);
val[id[e[i].x]] = e[i].val;
}
Build(,num,);
char str[];
while(~scanf("%s",str)) {
if(str[]=='D')break;
if(str[]=='C') {
scanf("%d%d",&u,&vv);
if(dep[e[u].x]<dep[e[u].y])swap(e[u].x,e[u].y);
change(,,n,id[e[u].x],vv);
} else if(str[]=='N'){
scanf("%d%d",&u,&vv);
solve(u,vv);
}else {
scanf("%d%d",&u,&vv);
if(u==vv)puts("");
else printf("%d\n",Yougth(u,vv));
}
} } return ;
}
HDU 3237 Tree(树链剖分)(线段树区间取反,最大值)的更多相关文章
- Aizu 2450 Do use segment tree 树链剖分+线段树
Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...
- 【POJ3237】Tree(树链剖分+线段树)
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
- HDU 2460 Network(双连通+树链剖分+线段树)
HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...
- POJ3237 Tree 树链剖分 线段树
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ3237 题意概括 Description 给你由N个结点组成的树.树的节点被编号为1到N,边被编号为1 ...
- 【CF725G】Messages on a Tree 树链剖分+线段树
[CF725G]Messages on a Tree 题意:给你一棵n+1个节点的树,0号节点是树根,在编号为1到n的节点上各有一只跳蚤,0号节点是跳蚤国王.现在一些跳蚤要给跳蚤国王发信息.具体的信息 ...
- Spoj Query on a tree SPOJ - QTREE(树链剖分+线段树)
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...
- Water Tree CodeForces 343D 树链剖分+线段树
Water Tree CodeForces 343D 树链剖分+线段树 题意 给定一棵n个n-1条边的树,起初所有节点权值为0. 然后m个操作, 1 x:把x为根的子树的点的权值修改为1: 2 x:把 ...
- Aragorn's Story 树链剖分+线段树 && 树链剖分+树状数组
Aragorn's Story 来源:http://www.fjutacm.com/Problem.jsp?pid=2710来源:http://acm.hdu.edu.cn/showproblem.p ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
随机推荐
- 七夕蠕虫“XX神器”逆向分析
转载请注明出处 ____________________________________________________________________________________________ ...
- elk-logstash: window下指定jdk目录
\bin\logstash.bat文件中, SETLOCAL的后面,CALL "%SCRIPT_DIR%\setup.bat" 的前面增加一行: @echo off SETLOCA ...
- Python学习-day20 django进阶篇
Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层执行 ...
- Box布局管理
创建wx.BoxSizer对象时可以指定布局方向: hbox = wx.BoxSizer(wx.HORIZONTAL) 设置为水平方向 hbox = wx.BoxSizer() 默认就是就是水平方向的 ...
- 安装启动Apache2.4后报Invalid command 'Order', perhaps misspelled or defined by a module not included in the server configuration错误
LoadModule access_compat_module modules/mod_access_compat.so 取消这一行模块的注释,再重启服务即可. 搜索 mod_access_compa ...
- eclipse importing maven projects 卡顿
导入一个maven工程后 一直显示 importing maven projects 9% 解决办法: 找到eclipse安装目录下的eclipse.ini 在最后加入 -vm $JAVA_HOME% ...
- sql 表数据转移另一张表
if not exists(select * from syscolumns where id=object_id('REMOTEDETECTION_2018')) begin SELECT * I ...
- UTXO是什么?
以易于理解的方式解释了比特币交易中的"UTXO" UTXO 2017年11月1日 让我们看看当你发一点硬币时会发生什么. 比特币交易通过UTXO执行.通过在比特硬币的所有交易中新生 ...
- 一些需要注意的ts
写了一段时间ts,在从头学习一遍,温故而之新 ts的一些技巧 1.巧用注释 通过/** */形式的注释可以给 TS 类型做标记,编辑器会有更好的提示: /** A cool guy. */ inter ...
- SSWR 跟 进一法除法
1.对于浮点数SSWR float x = 3.456; //保留到小数点后两位 ) + 0.5) / 100.0; //output b = 3.46; 2.对于整数SSWR float x ; ...