Tree(树链剖分+线段树延迟标记)
Tree
http://poj.org/problem?id=3237
Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions: 12268 | Accepted: 3159 |
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
Source
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<vector>
#define maxn 200005
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std; struct Tree{;
int Max,Min;
}tree[maxn<<];
int lazy[maxn<<];
int n;
int dep[maxn],fa[maxn],siz[maxn],son[maxn],id[maxn],top[maxn],cnt;
int co,head[maxn];
struct Edge {
int to, next;
}edge[maxn]; void Swap(int &x,int &y){
int t=x;x=-y;y=-t;
} void addedge(int u, int v) {
edge[cnt].to = v;
edge[cnt].next = head[u];
head[u] = cnt++;
}
struct sair{
int x,y,len;
}p[maxn]; void pushdown(int rt){
if(lazy[rt]){
/* tree[rt<<1].Max+=1;
tree[rt<<1|1].Max+=1;
tree[rt<<1].Min+=1;
tree[rt<<1|1].Min+=1;*/
Swap(tree[rt<<].Max,tree[rt<<].Min);
Swap(tree[rt<<|].Max,tree[rt<<|].Min);
lazy[rt<<]^=;
lazy[rt<<|]^=;
lazy[rt]=;
}
} 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 build(int l,int r,int rt){
lazy[rt]=;
if(l==r){
tree[rt].Max=tree[rt].Min=;
return;
}
int mid=(l+r)/;
build(lson);
build(rson);
pushup(rt);
} void add(int L,int R,int k,int l,int r,int rt){
if(L<=l&&R>=r){
tree[rt].Max=tree[rt].Min=k;
return;
}
pushdown(rt);
int mid=(l+r)/;
if(L<=mid) add(L,R,k,lson);
if(R>mid) add(L,R,k,rson);
pushup(rt);
} void nega(int L,int R,int l,int r,int rt){
if(L<=l&&R>=r){
Swap(tree[rt].Max,tree[rt].Min);
lazy[rt]^=;
return;
}
pushdown(rt);
int mid=(l+r)/;
if(L<=mid) nega(L,R,lson);
if(R>mid) nega(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);
int mid=(l+r)/;
int ans=-0x3f3f3f3f;
if(L<=mid) ans=max(ans,query(L,R,lson));
if(R>mid) ans=max(ans,query(L,R,rson));
pushup(rt);
return ans;
} void dfs1(int now,int f,int deep){
dep[now]=deep;
siz[now]=;
fa[now]=f;
int maxson=-;
for(int i=head[now];~i;i=edge[i].next){
if(edge[i].to != fa[now]) {
dfs1(edge[i].to,now,deep+);
siz[now]+=siz[edge[i].to];
if(siz[edge[i].to]>maxson){
maxson=siz[edge[i].to];
son[now]=edge[i].to;
}
}
}
} void dfs2(int now,int topp){
id[now]=++cnt;
top[now]=topp;
if(!son[now]) return;
dfs2(son[now],topp);
for(int i=head[now];~i;i=edge[i].next){
int vvv = edge[i].to;
if(vvv==son[now]||vvv==fa[now]) continue;
dfs2(vvv,vvv);
}
} int qRange(int x,int y){
int t1 = top[x], t2 = top[y];
int res = -0x3f3f3f3f;
while(t1 != t2) {
if(dep[t1] < dep[t2]) {
swap(t1, t2); swap(x, y);
}
res = max(res,query(id[t1], id[x], , n, ));
x = fa[t1]; t1 = top[x];
}
if(x == y) return res;
if(dep[x] > dep[y]) swap(x, y);
return max(res,query(id[son[x]], id[y], , n, ));
} void NRange(int x,int y){
int t1 = top[x], t2 = top[y];
while(t1 != t2) {
if(dep[t1] < dep[t2]) {
swap(t1, t2); swap(x, y);
}
nega(id[t1],id[x],,n,);
x = fa[t1]; t1 = top[x];
}
if(x == y) return;
if(dep[x] > dep[y]) swap(x, y);
nega(id[son[x]],id[y],,n,);
} void addRange(int x,int y,int k){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
add(id[top[x]],id[x],k,,n,);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
add(id[x],id[y],k,,n,);
} int main(){
int m,r;
int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
memset(head, -, sizeof head);
mem(dep,);
mem(fa,);
mem(siz,);
mem(son,);
mem(id,);
mem(top,);
int z,x,y;
co=;
cnt=;
for(int i=;i<n;i++){
scanf("%d %d %d",&p[i].x,&p[i].y,&p[i].len);
addedge(p[i].x,p[i].y);
addedge(p[i].y,p[i].x);
}
cnt=;
int xx;
dfs1(,,);
dfs2(,);
build(,n,);
for(int i=;i<n;i++){
if(dep[p[i].x]<dep[p[i].y]) xx=p[i].y;
else xx=p[i].x;
addRange(xx,xx,p[i].len);
}
char pos[];
while(~scanf("%s",pos)){
if(pos[]=='D') break;
scanf("%d %d",&x,&y);
if(pos[]=='C'){
p[x].len=y;
if(dep[p[x].x]<dep[p[x].y]) xx=p[x].y;
else xx=p[x].x;
addRange(xx,xx,p[x].len);
}
else if(pos[]=='N'){
NRange(x,y);
}
else if(pos[]=='Q'){
printf("%d\n",qRange(x,y));
}
}
}
}
Tree(树链剖分+线段树延迟标记)的更多相关文章
- 【POJ3237】Tree(树链剖分+线段树)
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
- POJ3237 Tree 树链剖分 线段树
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ3237 题意概括 Description 给你由N个结点组成的树.树的节点被编号为1到N,边被编号为1 ...
- Water Tree CodeForces 343D 树链剖分+线段树
Water Tree CodeForces 343D 树链剖分+线段树 题意 给定一棵n个n-1条边的树,起初所有节点权值为0. 然后m个操作, 1 x:把x为根的子树的点的权值修改为1: 2 x:把 ...
- 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 ...
- 【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, ...
- B20J_2243_[SDOI2011]染色_树链剖分+线段树
B20J_2243_[SDOI2011]染色_树链剖分+线段树 一下午净调这题了,争取晚上多做几道. 题意: 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成 ...
- BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )
BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
随机推荐
- 针对ROS5版本的配置导出和导入(迁移其他服务器)
1.在老ROS,导出当前系统配置export compact RouterOS 5.12 新增功能 export compact 命令,该命令简化了导出的参数,仅导出修改的配置,系统默 认配置参数将不 ...
- linux上很方便的上传下载文件工具rz和sz使用介绍
简单说就是,可以很方便地用这两个sz/rz工具,实现Linux下和Windows之间的文件传输(发送和接收),速度大概为10KB/s,适合中小文件.rz/sz 通过Zmodem协议传输数据 一般来 ...
- JpGraph使用详解http://5ydycm.blog.51cto.com/115934/177498 http://www.cnblogs.com/txw1958/archive/2013/08/18/php-charts.html
下载 在官方网站 http://www.aditus.nu/jpgraph/ 下载jpgraph,其中1.X系列是用于PHP4的,2.X系列是用于PHP5的. 安装 将下载的得到的jpgraph压缩文 ...
- 【洛谷】P1341 无序字母对(欧拉回路)
题目 传送门:QWQ 分析 快把欧拉回路忘光了. 欧拉回路大概就是一笔画的问题,可不可以一笔画完全图. 全图有欧拉回路当且仅当全图的奇数度数的点有0或2个. 2个时是一个点是起点,另一个是终点. 本题 ...
- C# implement java like CountDownLatch
CountDownLatch是在java1.5被引入的,跟它一起被引入的并发工具类还有CyclicBarrier.Semaphore.ConcurrentHashMap和BlockingQueue,它 ...
- 为solr增加用户验证
添加此功能主要是为了增加solr服务器的安全性,不能随便让人访问. 1. 在tomcat的F:\Tomcat 6.0.26_solr\conf\tomcat-users.xml添加用户角色并 ...
- Executor框架(一)Executor框架介绍
Executor框架简介 Executor框架的两级调度模型 在HotSpot VM的线程模型中,Java线程被一对一映射为本地操作系统线程.Java线程启动时会创建一个本地操作系统线程:当Jav ...
- Arrays.binarySearch 数组二分查找
public static void main(String[] args) throws Exception { /** * binarySearch(Object[], Object key) a ...
- js-传送file
这是选择文件的标签 <input type="file" class="add-image-input"> 这是js实现传输文件 var addIm ...
- 《GPU高性能编程CUDA实战》第七章 纹理内存
▶ 本章介绍了纹理内存的使用,并给出了热传导的两个个例子.分别使用了一维和二维纹理单元. ● 热传导(使用一维纹理) #include <stdio.h> #include "c ...