POJ 3237 /// 树链剖分 线段树区间修改(*-1)
题目大意:
给定树的N个结点 编号为1到N 给定N-1条边的边权。
三种操作:
CHANGE k w:将第 k 条边的权值改成 w。
NEGATE x y:将x到y的路径上所有边的权值乘 -1。
QUERY x y:找出x到y的路径上所有边的最大权值。
单点更新 区间更新 区间查询
由于第二个操作是乘 -1 所以需要同时维护最大值和最小值
所以 lazy用来标记是否乘-1 0表示不乘-1 1表示乘-1
http://www.cnblogs.com/HDUjackyan/p/9279777.html
#include <stdio.h>
#include <algorithm>
#include <cstring>
using namespace std;
#define INF 0x3f3f3f3f
#define mem(i,j) memset(i,j,sizeof(i))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define root 1,n,1 const int maxn=1e4+;
int n; struct IntervalTree {
struct EDGE { int to,ne; }e[maxn<<];
int head[maxn], tot;
void addE(int u,int v) {
e[tot].to=v;
e[tot].ne=head[u];
head[u]=tot++;
} int fa[maxn], son[maxn], dep[maxn], num[maxn];
int top[maxn], p[maxn], fp[maxn], pos; void init() {
tot=; mem(head,);
pos=; mem(son,);
} struct TREE {
int Max,Min,lazy;
}tree[maxn<<]; // --------------------以下是线段树------------------------- void pushUp(int rt) {
tree[rt].Max=max(tree[rt<<].Max,tree[rt<<|].Max);
tree[rt].Min=min(tree[rt<<].Min,tree[rt<<|].Min);
}
void pushDown(int rt,int m) {
if(m==) return;
if(tree[rt].lazy) {
tree[rt<<].Max*=-;
tree[rt<<].Min*=-;
tree[rt<<].lazy^=;
tree[rt<<|].Max*=-;
tree[rt<<|].Min*=-;
tree[rt<<|].lazy^=;
swap(tree[rt<<].Max,tree[rt<<].Min);
swap(tree[rt<<|].Max,tree[rt<<|].Min);
tree[rt].lazy=;
}
}
void build(int l,int r,int rt) {
if(l==r) {
tree[rt].Max=tree[rt].Min=tree[rt].lazy=;
return;
}
int m=(l+r)>>;
build(lson), build(rson);
pushUp(rt);
}
void update1(int k,int w,int l,int r,int rt) {
if(l==r) {
tree[rt].Max=tree[rt].Min=w;
tree[rt].lazy=;
return;
}
pushDown(rt,r-l+);
int m=(l+r)>>;
if(k<=m) update1(k,w,lson);
else update1(k,w,rson);
pushUp(rt);
}
void update2(int L,int R,int l,int r,int rt) {
if(L<=l && r<=R) {
tree[rt].Max*=-;
tree[rt].Min*=-;
tree[rt].lazy^=;
swap(tree[rt].Max,tree[rt].Min);
return ;
}
pushDown(rt,r-l+);
int m=(l+r)>>;
if(L<=m) update2(L,R,lson);
if(R>m) update2(L,R,rson);
pushUp(rt);
}
int query(int L,int R,int l,int r,int rt) {
if(L<=l && r<=R) return tree[rt].Max;
pushDown(rt,r-l+);
int m=(l+r)>>, res=-INF;
if(L<=m) res=max(res,query(L,R,lson));
if(R>m) res=max(res,query(L,R,rson));
pushUp(rt);
return res;
} // --------------------以上是线段树------------------------- // --------------------以下是树链剖分------------------------- void dfs1(int u,int pre,int d) {
dep[u]=d; fa[u]=pre; num[u]=;
for(int i=head[u];i;i=e[i].ne) {
int v=e[i].to;
if(v!=fa[u]) {
dfs1(v,u,d+);
num[u]+=num[v];
if(!son[u] || num[v]>num[son[u]])
son[u]=v;
}
}
}
void dfs2(int u,int sp) {
top[u]=sp; p[u]=++pos; fp[p[u]]=u;
if(!son[u]) return;
dfs2(son[u],sp);
for(int i=head[u];i;i=e[i].ne) {
int v=e[i].to;
if(v!=son[u] && v!=fa[u])
dfs2(v,v);
}
}
int queryPath(int x,int y) {
int fx=top[x], fy=top[y], ans=-INF;
while(fx!=fy) {
if(dep[fx]>dep[fy]) {
ans=max(ans,query(p[fx],p[x],root));
x=fa[fx];
} else {
ans=max(ans,query(p[fy],p[y],root));
y=fa[fy];
}
fx=top[x], fy=top[y];
}
if(x==y) return ans;
if(dep[x]>dep[y]) swap(x,y);
return max(ans,query(p[son[x]],p[y],root));
}
void updatePath(int x,int y) {
int fx=top[x], fy=top[y];
while(fx!=fy) {
if(dep[fx]>dep[fy]) {
update2(p[fx],p[x],root);
x=fa[fx];
} else {
update2(p[fy],p[y],root);
y=fa[fy];
}
fx=top[x], fy=top[y];
}
if(x==y) return ;
if(dep[x]>dep[y]) swap(x,y);
update2(p[son[x]],p[y],root);
} // --------------------以上是树链剖分------------------------- void initQTree() {
dfs1(,,), dfs2(,);
build(root);
}
}T;
int E[maxn][]; int main()
{
int t; scanf("%d",&t);
while(t--) {
scanf("%d",&n);
T.init();
for(int i=;i<n;i++) {
int u,v,w; scanf("%d%d%d",&u,&v,&w);
E[i][]=u, E[i][]=v, E[i][]=w;
T.addE(u,v), T.addE(v,u);
}
T.initQTree();
for(int i=;i<n;i++) {
if(T.dep[E[i][]]>T.dep[E[i][]])
swap(E[i][],E[i][]); //puts("OK");
T.update1(T.p[E[i][]],E[i][],root);
}
while() {
char s[]; scanf("%s",s);
if(s[]=='D') break;
int x,y; scanf("%d%d",&x,&y);
if(s[]=='Q')
printf("%d\n",T.queryPath(x,y));
else if(s[]=='C')
T.update1(T.p[E[x][]],y,root);
else if(s[]=='N')
T.updatePath(x,y);
}
} return ;
}
POJ 3237 /// 树链剖分 线段树区间修改(*-1)的更多相关文章
- POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 )
POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 ) 题意分析 给出n个点,m个询问,和当前位置pos. 先给出n-1条边,u->v以及边权w. 然后有m个询问 ...
- 【bzoj2325】[ZJOI2011]道馆之战 树链剖分+线段树区间合并
题目描述 给定一棵树,每个节点有上下两个格子,每个格子的状态为能走或不能走.m次操作,每次修改一个节点的状态,或询问:把一条路径上的所有格子拼起来形成一个宽度为2的长方形,从起点端两个格子的任意一个开 ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- 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 ...
- bzoj2243[SDOI2011]染色 树链剖分+线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 9012 Solved: 3375[Submit][Status ...
- B20J_2243_[SDOI2011]染色_树链剖分+线段树
B20J_2243_[SDOI2011]染色_树链剖分+线段树 一下午净调这题了,争取晚上多做几道. 题意: 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成 ...
- 2019西北工业大学程序设计创新实践基地春季选拔赛 I Chino with Rewrite (并查集+树链剖分+线段树)
链接:https://ac.nowcoder.com/acm/contest/553/I 思路:离线整棵树,用并查集维护下联通的情况,因为值只有60个,用2的x(1<=x<=60)次方表示 ...
随机推荐
- 关于提BUG的一点思考以及工作中总结的规范
在测试的工作中,提BUG是日常工作. 以前自己为了省事,省时,仅仅是截图,在图片上注明一下问题,就放到BUG库中了. 现在发现这样会造成开发的时间的浪费,增加了沟通成本. 对于BUG,当发现了异常时, ...
- 杂项-.Net-HQL:HQL
ylbtech-杂项-.Net-HQL:HQL HQL是Hibernate Query Language的缩写,提供更加丰富灵活.更为强大的查询能力:HQL更接近SQL语句查询语法. 1.返回顶部 1 ...
- vue 笔记,ref 及 $event 事件对象
本文仅用作简单记录 ref : 在标签上添加 ref = “name” ,表示获取当前元素节点 <input type="text" ref="info" ...
- WSGI是什么?
WSGI是什么? WSGI,全称 Web Server Gateway Interface,或者 Python Web Server Gateway Interface ,是为 Python 语言定义 ...
- git提交遇到.suo文件无法提交的问题
这个只是我个人遇到的一个问题小记 由于最近做的项目使用VS编辑器的,在用它集成创建的项目里,每次提交都会有个后缀名为.suo的文件在修改的文件列表里.这时直接进行提交会报错, 1.我将xx.suo/x ...
- Redis数据结构之快速列表-quicklist
链表 在Redis的早期版本中,存储list列表结构时,如果元素少则使用压缩列表ziplist,否则使用双向链表linkedlist // 链表节点 struct listNode<T> ...
- python面试题之你如何管理不同版本的代码?
答案: 版本管理!被问到这个问题的时候,你应该要表现得很兴奋,甚至告诉他们你是如何使用Git(或是其他你最喜欢的工具)追踪自己和奶奶的书信往来.我偏向于使用Git作为版本控制系统(VCS),但还有其他 ...
- 拓展KMP求回文串
题目:hdu3613: 题意:有26字母对应的价值,然后给出以个串,把它分成两段字串,如果字串是回文串,串的价值就是每个字符和,不是就为0.求最大价值. 博客 分析:拓展KMP的应用求回文字串. #i ...
- Ansible随笔8
自定义模块的开发模式 1.决定自定义模块的存放路径 编辑/etc/ansible/ansible.cfg文件,修改library = /usr/share/ansible/. 这样就告诉ansible ...
- layui 封装自定义模块
转自:https://lianghongbo.cn/blog/430585105a35948c layui是国人开发的一款非常简洁的UI框架,使用了模块化加载方式,因此在使用过程中我们难免需要添加自己 ...