「POJ3237」Tree(树链剖分)
题意
给棵n个点的树。边有边权然后有三种操作
1、CHANGE i v 将编号为i的边权变为v
2、NEGATE a b 将a到b的所有边权变为相反数。
3、QUERY a b 查询a b路径的最大边权。
(n,q<=10000)
题解
树剖裸题。
边权下放。线段树记录最大值最小值即可。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=;
int cnt,head[N];
int size[N],fa[N],dep[N],ww[N],son[N],ide[N];
int top[N],id[N],tot,w[N];
int t,n;
char s[];
struct edge{
int to,nxt,w,id;
}e[N*];
void add(int u,int v,int w,int id){
cnt++;
e[cnt].nxt=head[u];
e[cnt].to=v;
e[cnt].w=w;
e[cnt].id=id;
head[u]=cnt;
}
struct tree{
int l,r,maxx,minn,lazy;
}tr[N*];
void update(int now){
tr[now].maxx=max(tr[now*].maxx,tr[now*+].maxx);
tr[now].minn=min(tr[now*].minn,tr[now*+].minn);
}
void pushdown(int now){
if(tr[now].lazy==)return;
int hh=tr[now*].maxx;
tr[now*].maxx=-tr[now*].minn;
tr[now*].minn=-hh;
hh=tr[now*+].maxx;
tr[now*+].maxx=-tr[now*+].minn;
tr[now*+].minn=-hh;
tr[now*].lazy^=;
tr[now*+].lazy^=;
tr[now].lazy=;
}
void dfs1(int u,int f,int deep){
size[u]=;
fa[u]=f;
dep[u]=deep;
int maxson=-;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(v==f)continue;
ww[v]=e[i].w;
ide[e[i].id]=v;
dfs1(v,u,deep+);
size[u]+=size[v];
if(size[v]>maxson){
son[u]=v;
maxson=size[v];
}
}
}
void dfs2(int u,int tp){
top[u]=tp;
id[u]=++tot;
w[tot]=ww[u];
if(!son[u])return;
dfs2(son[u],tp);
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
void build(int l,int r,int now){
tr[now].l=l;tr[now].r=r;
tr[now].maxx=tr[now].lazy=tr[now].minn=;
if(l==r){
tr[now].maxx=tr[now].minn=w[l];
return;
}
int mid=(l+r)>>;
build(l,mid,now*);
build(mid+,r,now*+);
update(now);
}
int getmax(int l,int r,int now){
pushdown(now);
if(tr[now].l==l&&tr[now].r==r){
return tr[now].maxx;
}
int mid=(tr[now].l+tr[now].r)>>;
if(l>mid)return getmax(l,r,now*+);
else if(r<=mid)return getmax(l,r,now*);
else {
return max(getmax(l,mid,now*),getmax(mid+,r,now*+));
}
}
void change(int x,int y,int now){
pushdown(now);
if(tr[now].l==tr[now].r){
tr[now].maxx=tr[now].minn=y;
return;
}
int mid=(tr[now].l+tr[now].r)>>;
if(x>mid)change(x,y,now*+);
else if(x<=mid)change(x,y,now*);
update(now);
}
void getfan(int l,int r,int now){
pushdown(now);
if(tr[now].l==l&&tr[now].r==r){
tr[now].lazy^=;
int hh=tr[now].maxx;
tr[now].maxx=-tr[now].minn;
tr[now].minn=-hh;
return;
}
int mid=(tr[now].l+tr[now].r)>>;
if(l>mid)getfan(l,r,now*+);
else if(r<=mid)getfan(l,r,now*);
else{
getfan(l,mid,now*);
getfan(mid+,r,now*+);
}
update(now);
}
int getlca(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
x=fa[top[x]];
}
if(dep[x]<dep[y])return x;
else return y;
}
int getmaxl(int x,int y){
int ans=-;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans=max(ans,getmax(id[top[x]],id[x],));
x=fa[top[x]];
}
if(x==y)return ans;
if(dep[x]>dep[y])swap(x,y);
ans=max(ans,getmax(id[x]+,id[y],));
return ans;
}
void getfanl(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
getfan(id[top[x]],id[x],);
x=fa[top[x]];
}
if(x==y)return;
if(dep[x]>dep[y])swap(x,y);
getfan(id[x]+,id[y],);
}
int main(){
scanf("%d",&t);
for(int z=;z<=t;z++){
scanf("%d",&n);
memset(head,,sizeof(head));
memset(son,,sizeof(son));
memset(dep,,sizeof(dep));
memset(fa,,sizeof(fa));
memset(size,,sizeof(size));
memset(ide,,sizeof(ide));
memset(w,,sizeof(w));
memset(ww,,sizeof(ww));
memset(id,,sizeof(id));
memset(top,,sizeof(top));
tot=;
cnt=;
for(int i=;i<=n-;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w,i);
add(v,u,w,i);
}
dfs1(,,);
dfs2(,);
build(,n,);
while(scanf("%s",&s)!=EOF){
if(s[]=='D')break;
if(s[]=='Q'){
int x,y;
scanf("%d%d",&x,&y);
int LCA=getlca(x,y);
printf("%d\n",max(getmaxl(LCA,x),getmaxl(LCA,y)));
}
else if(s[]=='C'){
int x,y;
scanf("%d%d",&x,&y);
change(id[ide[x]],y,);
}
else if(s[]=='N'){
int x,y;
scanf("%d%d",&x,&y);
int LCA=getlca(x,y);
getfanl(LCA,x);
getfanl(LCA,y);
}
}
}
return ;
}
「POJ3237」Tree(树链剖分)的更多相关文章
- 【POJ3237】Tree 树链剖分+线段树
[POJ3237]Tree Description You are given a tree with N nodes. The tree's nodes are numbered 1 through ...
- 「HNOI2015」开店(树链剖分, 主席树)
/* 考虑将所求的值拆分 记每个点到根的路径长度为dis_i, 那么我们要求的就是\sum_{i = l} ^ r dis_i + dis[u] * (r - l + 1) - 2\sum_{i = ...
- POJ3237 Tree 树链剖分 边权
POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...
- Hdu 5274 Dylans loves tree (树链剖分模板)
Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...
- POJ3237 Tree 树链剖分 线段树
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ3237 题意概括 Description 给你由N个结点组成的树.树的节点被编号为1到N,边被编号为1 ...
- 【POJ3237】【树链剖分】Tree
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
- Query on a tree——树链剖分整理
树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...
- 【BZOJ-4353】Play with tree 树链剖分
4353: Play with tree Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 31 Solved: 19[Submit][Status][ ...
- SPOJ Query on a tree 树链剖分 水题
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...
随机推荐
- BZOJ 3166 set+可持久化trie树(OR 莫队)
思路: 1.找次大值 我们不妨设当前点是次大的 那这段区间为 左边第二个比它大的点的坐标+1 和右边第二个比它大的点的坐标-1 2.用可持久化trie树找异或最大值 也可以用莫队 //By Siriu ...
- RGB与16进制色互转
点击进入新版 <前端在线工具站> CSS, JavaScript 压缩YUI compressor, JSPacker...HTML特殊符号对照表PNG,GIF,JPG... Base ...
- 内部div自动扩张剩余宽度
<div id="container"> <div id="left">左边</div> <div id=" ...
- ActiveMQ学习笔记(3)----JMS的可靠性机制
1. 消息接收确认 JMS消息只有在被确认之后,才认为已经被成功的消费了,消息成功消费通常包含三个阶段:客户接收消息,客户处理消息和消息被确认. 在事务性会话中,当一个事务被提交的时候,确认自动发生. ...
- ActiveMQ学习笔记(1)----初识ActiveMQ
1. 什么是ActiveMQ? ActiveMQ是Apache推出的,一款开源的,完全支持JMS1.1和j2ee1.4规范的JMS Provider实现的消息中间件(Message Oriented ...
- Spring MVC 搭建过程中web.xml配置引入文件的路径问题
为啥要说一下这么low的问题,因为我是一个比较low的人,哈哈.本来我技术有限,没事干自己撘个环境找找乐趣,结果被各种基础问题,弄的一脸蒙蔽.算了不多说,直接说问题. 1.首先说一下java编译后的文 ...
- centos7.3安装php7.0
需求:在Centos7.3下搭建LNMP环境 文章转载自:http://blog.csdn.net/wszll_alex/article/details/76285324 作者:狂热森林 . 关闭防火 ...
- [Java] 使用 Apache的 Commons-net库 实现FTP操作
因为最近工作中需要用到FTP操作,而手上又没有现成的FTP代码.就去网上找了一下,发现大家都使用Apache的 Commons-net库中的FTPClient. 但是,感觉用起来不太方便.又在网上找到 ...
- 仿百度排列图片预览插件-Simple Lightbox
很久以前遇到过这样的一个面试题,要求手写代码,实现百度图片的排列预览,并且可以左右点击查看下一张照片,当时没有做出来,这个问题也就一直放在了脑后,工作之后,遇到这样的需求之后,第一反应想到的是在源码网 ...
- HDU 4366 Successor
Successor Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on HDU. Original ID: ...