Tree
Time Limit: 5000MS   Memory Limit: 131072K
Total Submissions: 9123   Accepted: 2411

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
【分析】题意很好理解,唯一的难点就是将某一区间内的数变成相反数,需要用到懒惰标记。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <time.h>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#define met(a,b) memset(a,b,sizeof a)
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
typedef long long ll;
const int N=2e5+;
const int M=N*N+;
int dep[N],siz[N],fa[N],id[N],son[N],val[N],top[N]; //top 最近的重链父节点
int num,s,m,n,q;
int sum[N*],tre[*N];
int maxn[N],minn[N],lazy[N];
vector<int> v[N];
struct tree {
int x,y,val;
void read() {
scanf("%d%d%d",&x,&y,&val);
}
} e[N];
void dfs1(int u, int f, int d) {
dep[u] = d;
siz[u] = ;
son[u] = ;
fa[u] = f;
for (int i = ; i < v[u].size(); i++) {
int ff = v[u][i];
if (ff == f) continue;
dfs1(ff, u, d + );
siz[u] += siz[ff];
if (siz[son[u]] < siz[ff])
son[u] = ff;
}
}
void dfs2(int u, int tp) {
top[u] = tp;
id[u] = ++num;
if (son[u]) dfs2(son[u], tp);
for (int i = ; i < v[u].size(); i++) {
int ff = v[u][i];
if (ff == fa[u] || ff == son[u]) continue;
dfs2(ff, ff);
}
}
void ChangeVal(int rt) {
int tmp=maxn[rt];
maxn[rt]=-minn[rt];
minn[rt]=-tmp;
}
void Push_up(int rt) {
maxn[rt]=max(maxn[*rt],maxn[*rt+]);
minn[rt]=min(minn[*rt],minn[*rt+]);
}
void Push_down(int rt) {
if(lazy[rt]) {
lazy[rt]^=;
lazy[*rt]^=;
ChangeVal(rt*);
lazy[*rt+]^=;
ChangeVal(*rt+);
}
}
void change(int t,int l,int r,int x,int v){
if(l==r) maxn[t]=minn[t]=v;
else{
Push_down(t);
int mid=(l+r)>>;
if(x<=mid) change(t*,l,mid,x,v);
else change(t*+,mid+,r,x,v);
Push_up(t);
}
}
void Build(int l,int r,int rt) {
if(l==r) {
maxn[rt]=minn[rt]=val[l];
return;
}
int m=(l+r)>>;
Build(lson);
Build(rson);
Push_up(rt);
//printf("rt=%d sum[rt]=%d\n",rt,sum[rt]);
} void Update(int L,int R,int l,int r,int rt) {
if(l>=L&&r<=R) {
lazy[rt]^=;
ChangeVal(rt);
return;
}
Push_down(rt);
int m=(r+l)>>;
if(L<=m)Update(L,R,lson);
if(R>m) Update(L,R,rson);
Push_up(rt);
} int Query(int L,int R,int l,int r,int rt) {
if(L<=l&&r<=R)return maxn[rt];
Push_down(rt);
int m=(l+r)>>;
if(R<=m)return Query(L,R,lson);
else if(L>m)return Query(L,R,rson);
else return max(Query(L,m,lson),Query(m+,R,rson));
} void solve(int u, int v) {
int tp1 = top[u], tp2 = top[v];
int ans = ;
while (tp1 != tp2) {
if (dep[tp1] < dep[tp2]) {
swap(tp1, tp2);
swap(u, v);
}
Update(id[tp1],id[u],,n,);
u = fa[tp1];
tp1 = top[u];
}
if (u == v) return;
if (dep[u] > dep[v]) swap(u, v);
Update(id[son[u]],id[v],,n,);
return;
}
int Yougth(int u,int v) {
int tp1 = top[u], tp2 = top[v];
int ans=-;
while (tp1 != tp2) {
if (dep[tp1] < dep[tp2]) {
swap(tp1, tp2);
swap(u, v);
}
ans = max(Query(id[tp1], id[u],,n,),ans);
u = fa[tp1];
tp1 = top[u];
}
if (u == v) return ans;
if (dep[u] > dep[v]) swap(u, v);
ans = max(Query(id[son[u]], id[v],,n,),ans);
return ans;
}
void Clear(int n) {
for(int i=; i<=n; i++)
v[i].clear();
met(son,);met(maxn,);met(minn,);
met(lazy,);
}
int main() {
int t;
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
Clear(n);
int u,vv,w;
for(int i=; i<n; i++) {
e[i].read();
v[e[i].x].push_back(e[i].y);
v[e[i].y].push_back(e[i].x);
}
num = ;
dfs1(,,);
dfs2(,);
for (int i = ; i < n; i++) {
if (dep[e[i].x] < dep[e[i].y]) swap(e[i].x, e[i].y);
val[id[e[i].x]] = e[i].val;
}
Build(,num,);
char str[];
while(~scanf("%s",str)) {
if(str[]=='D')break;
if(str[]=='C') {
scanf("%d%d",&u,&vv);
if(dep[e[u].x]<dep[e[u].y])swap(e[u].x,e[u].y);
change(,,n,id[e[u].x],vv);
} else if(str[]=='N'){
scanf("%d%d",&u,&vv);
solve(u,vv);
}else {
scanf("%d%d",&u,&vv);
if(u==vv)puts("");
else printf("%d\n",Yougth(u,vv));
}
} } return ;
}

HDU 3237 Tree(树链剖分)(线段树区间取反,最大值)的更多相关文章

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

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

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

  3. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  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. Aragorn's Story 树链剖分+线段树 && 树链剖分+树状数组

    Aragorn's Story 来源:http://www.fjutacm.com/Problem.jsp?pid=2710来源:http://acm.hdu.edu.cn/showproblem.p ...

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

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

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

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

随机推荐

  1. [网站公告]又拍云API故障造成图片无法上传

    大家好,今天早上8:30左右发现又拍云API出现故障,造成图片无法上传,调用图片上传API时出现错误:“The operation has timed out”. 该故障给大家带来了麻烦,望大家谅解! ...

  2. MySQL增强半同步几个重要参数搭配的测试

      Preface       Semi-synchronous replication is supported since MySQL 5.5 and then enhanced graduall ...

  3. jeakins忘记密码时的处理(简单粗暴)

    1.打开config文件(通过ps -elf | grep jenkins查看JENKINS_HOME目录,然后在目录下查找config.xml文件) 2.修改<useSecurity>t ...

  4. Grid 布局管理器

    Grid 布局管理器: Grid布局类wx.GridSizer,Grid布局以网格形式对子窗口或控件进行摆放,容器被分成大小相等的矩形,一个矩形中放置一个子窗口或控件. wx.GridSizer构造方 ...

  5. 普通用户操作tomcat项目时报:Neither the JAVA_HOME nor the JRE_HOME environment variable is defined At least one of these environment variable is needed to run this program

    在使用普通用户更新tomcat项目适合出现这个信息,Neither the JAVA_HOME nor the JRE_HOME environment variable is defined At ...

  6. iOS 实现设备应用之间的相互切换

    今天突发奇想,想做个应用之间能够切换的demo. 前提条件是,你得知道对应应用程序的URL Scheme.URL Scheme不一定和bundle id相同,但是,一定要是一致的. [[UIAppli ...

  7. 【JAVA进阶】——myEclipse连接mysql启动数据库服务

    背景: DRP项目要求使用Oracle数据库,但目前由于种种原因,暂时还装不了Oracle.但也不能闲着啊,就拿mysql来试试.安装完mysql以后,使用myEclipse连接数据库,就一直报错,报 ...

  8. Linux命令 -磁盘和文件系统类

    声明:本文所涉及到的Linux命令均为最常见的用法,未列举之参数,自行查阅man 1.df 磁盘容量 -h 以人类易读方式展示(GB.KB)等 df -h /usr 2.du 文件或目录的容量 -s ...

  9. Linux下从零开始部署和使用Jaeger

    最近在折腾Jaeger,Jaeger官网都是介绍如何通过Docker部署,二进制部署文档基本没有(已咨询过作者,作者说没文档!你参考Docker自己部署好了!!!),所以打算写一篇Linux部署. J ...

  10. Hadoop入门(五) Hadoop2.7.5集群分布式环境搭建

    本文接上文内容继续: server01 192.168.8.118 jdk.www.fengshen157.com/ hadoop NameNode.DFSZKFailoverController(z ...