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 ab 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(树链剖分+线段树延迟标记)的更多相关文章

  1. 【POJ3237】Tree(树链剖分+线段树)

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

  2. POJ3237 Tree 树链剖分 线段树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ3237 题意概括 Description 给你由N个结点组成的树.树的节点被编号为1到N,边被编号为1 ...

  3. Water Tree CodeForces 343D 树链剖分+线段树

    Water Tree CodeForces 343D 树链剖分+线段树 题意 给定一棵n个n-1条边的树,起初所有节点权值为0. 然后m个操作, 1 x:把x为根的子树的点的权值修改为1: 2 x:把 ...

  4. 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 ...

  5. 【CF725G】Messages on a Tree 树链剖分+线段树

    [CF725G]Messages on a Tree 题意:给你一棵n+1个节点的树,0号节点是树根,在编号为1到n的节点上各有一只跳蚤,0号节点是跳蚤国王.现在一些跳蚤要给跳蚤国王发信息.具体的信息 ...

  6. 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, ...

  7. B20J_2243_[SDOI2011]染色_树链剖分+线段树

    B20J_2243_[SDOI2011]染色_树链剖分+线段树 一下午净调这题了,争取晚上多做几道. 题意: 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成 ...

  8. BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )

    BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...

  9. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  10. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

随机推荐

  1. LVM逻辑卷创建管理

    首先添加三块硬盘 结构关系图 相关命令 查看磁盘 #fdisk -l 分区 #fdisk /dev/sda/ #n新建 ProMary主分区 extended扩展分区 #p查看 #q不保存退出 #w保 ...

  2. 【转载】html中object标签详解

    [转载自http://blog.csdn.net/soliy/archive/2010/03/22/5404183.aspx] html标签之Object标签详解 作者:网络    出处:网络     ...

  3. python的return self的用法

    转载:https://blog.csdn.net/jclian91/article/details/81238782 class foo: def __init__(self): self.m = 0 ...

  4. eclipse 常用jar包总结

    BeanUtils: DbUtils: FileUpload: IO: Lang: Logging: cglib: mysql-connector: Pool:[datasource] DBCP:[d ...

  5. spark sql 的性能调优

    Caching Data in Memory 其他调优参数

  6. 阿里数据服务P6~P7晋升要点

    这是我在2015年高德负责P6晋升评审为团队成员准备的要点,整理下. 1. 数据仓库难点 1.1 分布式OLAP设计与选型 传统BI 友盟,Talking Data 启明星 keylin phonie ...

  7. ORACLE中CONNECT BY...START WITH...的使用

    源: https://docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm http://www.cnblogs.com/baiy ...

  8. python中键值叫唤例子

    >>> myDict = {'a':'A','b':'B','c':'C'} >>> myDict {'a': 'A', 'c': 'C', 'b': 'B'} & ...

  9. UVA375

    题意: 已知等腰三角形的高H,底边长B,这时有一个内切圆C, 以内切圆C和长度为B对应的角的角平分线的交点做切线. 切线与角平分线相交,此时切线,和俩边又会出现一个小的等腰三角形,也有一个小的内切圆C ...

  10. ASCII和万国码

    ASCII和万国码 什么是ASCII 计算机的起初是使用内存中的0101来表示数和机器码.如何用内存中的bit来表示文本一直困扰着人们,毕竟人类主要的信息展示是文字,而不是苦涩的0101.后来ASCI ...