「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, ...
随机推荐
- weboffice7
document.all.WebOffice1.ShowToolBar = false;
- JavaScript中Array方法总览
title: JavaScript中Array方法总览 toc: true date: 2018-10-13 12:48:14 push(x) 将x添加到数组最后,可添加多个值,返回数组长度.改变原数 ...
- 页面的URL分析----window.location.href
window.location是页面的位置对象window.location.href是 location的一个属性值,并且它是location的默认属性. window.location直接赋值一个 ...
- js函数 DOM操作
回学校了两天请了两天假,数组和方法的内容周末一定补上! 今天介绍一下JavaScript函数 Function 一.基础内容 1.定义 函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块. f ...
- 【原创】Apache集群报Service Temporarily Unavailable的解决
Apache的集群突然时不时的报出以下错误: Service Temporarily Unavailable The server is temporarily unable to service y ...
- Linux 安装软件的几种方式
目录 几种安装方式 源代码编译安装 借助软件包管理器安装 二进制格式安装 总结 参考 几种安装方式 源代码编译安装 源代码包的安装一般为下载软件源代码,然后编译安装.常见的 C 程序软件的安装步骤是 ...
- 3dmax实例教程-使用3ds Max 创建一个完整的场景
本篇教程讲述了利用3ds max创建一个完整的场景. 灵感来源:当我在遇到一些事情睡不着觉的时候我便在努力想象一些别的事情,于是我便想到了这个场景,其实对于我的这个角色我即没有参考图也没有草稿图,有的 ...
- [Python随笔]>>字符串大小写是如何转换的?
首先看下Python的源码 Emmmm,说明是底层的C实现的,所以只放了说明 再看看别人家孩子的博客:https://blog.csdn.net/world6/article/details/6994 ...
- codeforces 914 D Bash and a Tough Math Puzzle
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #i ...
- 大O时间复杂度
大O表示法指出了在最糟情况下的运行时间.比较操作数,指出了算法运行时间的增速 常见的大O运行时间 O(logn):也叫对数时间,包括二分查找 O(n):也叫线性时间,包括简单查找 O(nlogn):包 ...