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. ESXI5.5设置主机的时间自动同步服务 NTP

    背景:现在公司的很多线上服务也都通过虚拟化来实现,最近遇到一个小问题,虚拟机上的时间不准确.原来是虚拟机会主动同步宿主机时间,一般虚拟机中都安装vmware tool工具,这个工具会自动和宿主机进行时 ...

  2. file_get_contents是打工文件或URL获取内容的方法,比其稳定的还有curl_get_contents

    相信使用过file_get_contents函数的朋友都知道,当获取的$url访问不了时,会导致页面漫长的等待,甚至还能导致PHP进程占用CPU达100%,因此这个函数就诞生了 分享一个实际在用的函数 ...

  3. eclipse在线安装jd反编译插件

    eclipse在线安装jd反编译插件地址 http://jd.benow.ca/jd-eclipse/update

  4. Storm集成Kafka的Trident实现

      原本打算将storm直接与flume直连,发现相应组件支持比较弱,topology任务对应的supervisor也不一定在哪个节点上,只能采用统一的分布式消息服务Kafka.   原本打算将结构设 ...

  5. js && Jquery 的回车事件

    有时候我们需要捕获页面上的回车事件,以达到一些特殊效果,例如在登录页面用户输入完登录名和密码后习惯直接敲回车,这时需要捕获回车事件,在回车事件中激活form元素 1.纯Java Script版 首先要 ...

  6. python2 与python3中最大的区别(编码问题bytes&str

    1,在python2.x 中是不区分bytes和str类型的,在python3中bytes和str中是区分开的,str的所有操作bytes都支持 python2 中 >>> s = ...

  7. sencha touch 小米3无法点击问题 修复

    修改源码文件夹下event/publisher/Dom.js中的attachListener方法,代码如下 attachListener: function(eventName, doc) { if ...

  8. python入门-字典

    1 python是使用{}来表示字典 字典是一系列的键值对 alien_0={} 2 访问字典中的值 new_point = alien_0['point'] print("you just ...

  9. JAVA 连接 Redis 并进行操作

    1, 这里以maven项目为例 <!-- Redis NoSQL 操作依赖 --> <dependency> <groupId>redis.clients</ ...

  10. as3 声明变量

    var a:int=0, b, c:Number=2; trace(a,b,c) /* 0 undefined 2 */ var a:int, b:uint, c:Number; var d:Stri ...