「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, ...
随机推荐
- 整数转罗马数字 C++实现 java实现 leetcode系列(十二)
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 写做 II ,即为两个并 ...
- BZOJ 3166 set+可持久化trie树(OR 莫队)
思路: 1.找次大值 我们不妨设当前点是次大的 那这段区间为 左边第二个比它大的点的坐标+1 和右边第二个比它大的点的坐标-1 2.用可持久化trie树找异或最大值 也可以用莫队 //By Siriu ...
- MEF基本概念
基本概念: Managed Extensibility Framework 或 MEF 是一个用于创建可扩展的轻型应用程序的库,在.NET 4.0发布 Container:容器,使用Compositi ...
- OpenGL编程(六)通过三角形绘画出3D模型
使用三角形绘制3D模型 三角形是基本的多边形,任何多变形都能由三角形组成.三角形是由三个顶点的连线组成.三个点分别是v0:v1:v2. 1.绕法 从某个顶点开始,有两种连线的方法,顺时针和逆时针,这是 ...
- centos下nginx配置
转自 http://www.linuxidc.com/Linux/2016-09/134907.htm 安装所需环境 Nginx 是 C语言 开发,建议在 Linux 上运行,当然,也可以安装 Wi ...
- php如何实现文件下载
php如何实现文件下载 1. 设置超链接的href属性 <ahref="文件地址"></a> 如果浏览器不能解析该文件,浏览器会自动下载.而如果文件是图片或 ...
- 关于Subversion主从备份方式的调整(全量、增量脚本)更新
本文引用于http://blog.chinaunix.net/uid-25266990-id-3369172.html 之前对Subversion服务器作了迁移,关于SVN的架构也走了调整,有单一的服 ...
- Python排序 插入排序
插入排序从前往后遍历数组的每一个元素,对每一位元素都将其插入到已经有序的部分数组中,所以插入排序的要点就是找出要插入元素在已经有序的部分中的位置,同时,由于插入排序采用原地排序(in-place)算法 ...
- Qt之OpenSSL
简述 OpenSSL是一个强大的安全套接字层密码库,囊括主要的密码算法.常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用. 简述 下载安装 使用 更多参考 下载安装 ...
- 三层登录—c#
学习了三层,有一个登录窗口的小练习.是我们第一次接触三层的初战.如今仅仅是简单的了解了一些,须要学习的还有非常多,以下浅谈自己的理解. 我们说的三层就是分层了显示层.业务逻辑层和数据訪问层.当中显示层 ...