Tree
Time Limit: 5000MS   Memory Limit: 131072K
Total Submissions: 7268   Accepted: 1969

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

【思路】

树链剖分,线段树。

又练了一边线段树<_<,bug满天飞T^T,线段树还得再做点题。

线段树:维护mx mn分别代表线段最大最小值,对于NEGATE操作打一个f标记,作用时直接将mx mn取负后交换即可。注意一下pushdown和maintain。

【代码】

 #include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
#include<algorithm>
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; const int N = +;
const int INF = 1e9; struct Node { int l,r,mx,mn,f;
}T[N<<];
struct Edge {
int u,v,w;
Edge(int u=,int v=,int w=) :u(u),v(v),w(w) {};
};
int n,q,z,d[N][];
vector<Edge> es;
vector<int> g[N]; void adde(int u,int v,int w) {
es.push_back(Edge(u,v,w));
int m=es.size();
g[u].push_back(m-);
}
//INIT
int top[N],son[N],dep[N],fa[N],siz[N],w[N];
void dfs1(int u) {
son[u]=; siz[u]=;
for(int i=;i<g[u].size();i++) {
int v=es[g[u][i]].v; //
if(v!=fa[u]) {
fa[v]=u , dep[v]=dep[u]+;
dfs1(v);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]]) son[u]=v;
}
}
}
void dfs2(int u,int tp) {
top[u]=tp; w[u]=++z;
if(son[u]) dfs2(son[u],tp);
for(int i=;i<g[u].size();i++) {
int v=es[g[u][i]].v;
if(v!=fa[u] && v!=son[u]) dfs2(v,v);
}
}
//SEGMENT TREE
//标记 该结点已被作用而子结点仍未作用
//pushdown 作用于访问节点 即只要访问就pushdown
void pushdown(int u) { //下传标记 同时作用于子结点
if(T[u].f && T[u].l<T[u].r) {
int lc=u<<,rc=lc|;
T[u].f=;
T[lc].f^= ,T[rc].f^=;
int t;
t=T[lc].mn,T[lc].mn=-T[lc].mx,T[lc].mx=-t;
t=T[rc].mn,T[rc].mn=-T[rc].mx,T[rc].mx=-t;
}
}
void maintain(int u) {
T[u].mx=max(T[u<<].mx,T[u<<|].mx);
T[u].mn=min(T[u<<].mn,T[u<<|].mn);
}
void build(int u,int L,int R) {
T[u].l=L,T[u].r=R;
T[u].mn=INF , T[u].mx=-INF , T[u].f=;
if(L==R) return ; //
int M=(L+R)>>;
build(u<<,L,M) , build(u<<|,M+,R);
}
void change(int u,int r,int x) {
pushdown(u); //
if(T[u].l==T[u].r) T[u].mn=T[u].mx=x;
else {
int M=(T[u].l+T[u].r)>>; //
if(r<=M) change(u<<,r,x);
else change(u<<|,r,x);
maintain(u);
}
}
void Negate(int u,int L,int R) {
pushdown(u);
if(L<=T[u].l && T[u].r<=R) {//打标记 同时作用于当前结点
T[u].f=;
int t; t=T[u].mn,T[u].mn=-T[u].mx,T[u].mx=-t; //
}
else {
int M=(T[u].l+T[u].r)>>;
if(L<=M) Negate(u<<,L,R);
if(M<R) Negate(u<<|,L,R);
maintain(u);
}
}
int query(int u,int L,int R) {
pushdown(u);
if(L<=T[u].l && T[u].r<=R) return T[u].mx;
else {
int M=(T[u].l+T[u].r)>>;
int ans=-INF;
if(L<=M) ans=max(ans,query(u<<,L,R));
if(M<R) ans=max(ans,query(u<<|,L,R));
return ans;
}
} //树链剖分
void modify(int u,int v) {
while(top[u]!=top[v]) {
if(dep[top[u]]<dep[top[v]]) swap(u,v);
Negate(,w[top[u]],w[u]);
u=fa[top[u]];
}
if(u==v) return ;
if(dep[u]>dep[v]) swap(u,v);
Negate(,w[son[u]],w[v]); //
}
int query(int u,int v) {
int mx=-INF;
while(top[u]!=top[v]) {
if(dep[top[u]]<dep[top[v]]) swap(u,v);
mx=max(mx,query(,w[top[u]],w[u]));
u=fa[top[u]];
}
if(u==v) return mx;
if(dep[u]>dep[v]) swap(u,v);
mx=max(mx,query(,w[son[u]],w[v]));
return mx;
} void read(int& x) {
char c=getchar();
while(!isdigit(c)) c=getchar();
x=;
while(isdigit(c))
x=x*+c-'' , c=getchar();
}
int main() {
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout);
int T; read(T);
while(T--) {
read(n);
z=; es.clear();
FOR(i,,n) g[i].clear();
int u,v,c;
FOR(i,,n-) {
read(u),read(v),read(c);
d[i][]=u,d[i][]=v,d[i][]=c;
adde(u,v,c),adde(v,u,c);
}
dfs1(),dfs2(,);
build(,,z);
FOR(i,,n-) {
if(dep[d[i][]]<dep[d[i][]]) swap(d[i][],d[i][]);
change(,w[d[i][]],d[i][]);
}
char s[];
while(scanf("%s",s)== && s[]!='D') {
read(u),read(v);
if(s[]=='C') change(,w[d[u][]],v);
else if(s[]=='N') modify(u,v);
else printf("%d\n",query(u,v));
}
}
return ;
}

poj 3237 Tree(树链剖分,线段树)的更多相关文章

  1. POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 )

    POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 ) 题意分析 给出n个点,m个询问,和当前位置pos. 先给出n-1条边,u->v以及边权w. 然后有m个询问 ...

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

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

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

  4. POJ3237 Tree 树链剖分 线段树

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

  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. Water Tree CodeForces 343D 树链剖分+线段树

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

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

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

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

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

  10. B20J_3231_[SDOI2014]旅行_树链剖分+线段树

    B20J_3231_[SDOI2014]旅行_树链剖分+线段树 题意: S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,城市信仰不同的宗教,为了方便,我们用不同的正整数代表各种宗教. S国 ...

随机推荐

  1. Codevs 1427 特种部队(双路DP)

    1427 特种部队 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 黄金 Gold 题目描述 Description 某特种部队接到一个任务,需要潜入一个仓库.该部队士兵分为两路,第一 ...

  2. zabbix 配置

    终于把zabbix配置好了.可能还有待优化   我主要参考了几个链接 http://lnmp.org/install.html   一键安装lnmp http://blog.unix178.com/2 ...

  3. linux 文件操作编程

    Linux中所有的设备和文件的操作都使用文件描述符来进行. 文件描述符是一个非负的整数,它是一个索引值,指向内核中每个进程打开的记录表. 当打开一个文件或者创建一个新文件时,内核就向进程返回一个文件描 ...

  4. 网站开发常用jQuery插件总结(12)固定元素插件scrolltofixed

    这个插件在前段时间用过一次,当时是改一个网站.要求顶部的菜单栏随着滚动条的滚动而固定.也大体写了一下,不过在文章中也只是提了一下,文章地址:jQuery插件固定元素位置. 在这篇文章中,再进行总结一下 ...

  5. 解决DataGridView.DataSource重复赋值而不显示问题

    List<Person> list=new List<Person>(); ;i<;i++) { list.Add(new Person(){........}) } d ...

  6. html网页音乐播放器自带播放列表

    基于网页的音乐播放器demo  http://pan.baidu.com/s/1dDgm7HR 自己diy了一个手机端在线音乐播放器演示地址http://shanxi2014.com/zhuandiz ...

  7. 简单的介绍下WPF中的MVVM框架

    最近在研究学习Swift,苹果希望它迅速取代复杂的Objective-C开发,引发了一大堆热潮去学它,放眼望去各个培训机构都已打着Swift开发0基础快速上手的招牌了.不过我觉得,等同于无C++基础上 ...

  8. POJ 1472 Instant Complexity 应该叫它编程题。。

    题目:http://poj.org/problem?id=1472 这个题目是分到“模拟题”一类的,我觉得模拟的成分比较少,主要考察编程能力.独立写完这个题特别兴奋...所以我必须好好说一说,独家哦. ...

  9. JavaMail 发送邮件

    JavaMail邮件发送 引用maven jar包 <dependency> <groupId>javax.mail</groupId> <artifactI ...

  10. js带缩略图的图片切换效果

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...