Tree
Time Limit: 5000MS   Memory Limit: 131072K
Total Submissions: 7384   Accepted: 2001

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
/*
poj3237 树链部分
感觉是比较不错的题目,主要是线段树掌握不怎么好导致一直有问题。
查询最大值 + 修改边 + 区间置反
先处理出树链,然后再上值
push_up 和 push_down函数
hhh-2016-2-2 3:46:58
*/ #include <functional>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <Map>
using namespace std;
typedef long long ll;
typedef long double ld; using namespace std; const int maxn = 100010; struct node
{
int to,next;
} edge[maxn*2]; int head[maxn];
int top[maxn]; //链的顶端节点
int far[maxn]; //父亲
int dep[maxn]; //深度
int num[maxn]; //表示以x为根的子树的节点数
int p[maxn]; //p[u]表示边u所在的位置
int fp[maxn]; //与p相对应
int son[maxn]; //重儿子
int tot,pos;
void addedge(int u,int v)
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot ++;
} void dfs(int u,int fa,int d) //先处理出重儿子、dep、far、num
{
dep[u] = d;
far[u] = fa;
num[u] = 1;
for(int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].to;
if(v != fa)
{
dfs(v,u,d+1);
num[u] += num[v];
if(son[u] == -1 || num[v] > num[son[u]])
son[u] = v;
}
}
} void getpos(int u,int sp)
{
top[u] = sp;
p[u] = pos++;
fp[p[u]] = u;
if(son[u] == -1) return ;
getpos(son[u],sp);
for(int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].to;
if(v != far[u] && v != son[u])
getpos(v,v);
}
} struct Node
{
int l,r;
int flag;
int Max,Min;
} segtree[maxn*3]; void build(int i,int l,int r)
{
segtree[i].l = l;
segtree[i].r = r;
segtree[i].Max = 0;
segtree[i].Min = 0;
segtree[i].flag = 0;
if(l == r)
return ;
int mid = (l+r)/2;
build(i<<1,l,mid);
build((i<<1)|1,mid+1,r);
} void push_up(int i)
{
segtree[i].Max = max(segtree[i<<1].Max,segtree[(i<<1)|1].Max);
segtree[i].Min = min(segtree[i<<1].Min,segtree[(i<<1)|1].Min);
} void push_down(int i)
{
if(segtree[i].l == segtree[i].r)
return ;
if(segtree[i].flag)
{
segtree[i<<1].Max = -segtree[i<<1].Max;
segtree[i<<1].Min = -segtree[i<<1].Min;
swap(segtree[i<<1].Max,segtree[i<<1].Min);
segtree[i<<1].flag ^= 1; segtree[(i<<1)|1].Max = -segtree[(i<<1)|1].Max;
segtree[(i<<1)|1].Min = -segtree[(i<<1)|1].Min;
segtree[(i<<1)|1].flag ^= 1;
swap(segtree[(i<<1)|1].Max,segtree[(i<<1)|1].Min); segtree[i].flag = 0;
}
} void update(int i,int k,int val)
{
if(segtree[i].l == k && segtree[i].r == k)
{
segtree[i].Max = val;
segtree[i].Min = val;
segtree[i].flag = 0;
return ;
}
push_down(i);
int mid = (segtree[i].l+segtree[i].r)>>1;
if(k <= mid) update(i<<1,k,val);
else update((i<<1)|1,k,val);
push_up(i);
} void negat(int i,int l,int r)
{
if((segtree[i].l == l && segtree[i].r == r))
{
segtree[i].Max = -segtree[i].Max;
segtree[i].Min = -segtree[i].Min;
swap(segtree[i].Max,segtree[i].Min);
segtree[i].flag ^= 1;
return;
}
push_down(i);
int mid = (segtree[i].l+segtree[i].r)>>1;
if(r <= mid) negat(i<<1,l,r);
else if(l > mid) negat((i<<1)|1,l,r);
else
{
negat(i<<1,l,mid);
negat((i<<1)|1,mid+1,r);
}
push_up(i);
} int query(int i,int l,int r)
{
if(segtree[i].l == l && segtree[i].r == r)
{
return segtree[i].Max;
}
push_down(i);
int mid = (segtree[i].l+segtree[i].r)>>1;
if(r <= mid) return query(i<<1,l,r);
else if(l > mid) return query((i<<1)|1,l,r);
else return max(query(i<<1,l,mid),query((i<<1)|1,mid+1,r));
push_up(i);
} int fin(int l,int r)
{
int f1 = top[l];
int f2 = top[r];
int tt = -100000000;
while(f1 != f2)
{
if(dep[f1] < dep[f2])
{
swap(f1,f2);
swap(l,r);
}
tt = max(query(1,p[f1],p[l]),tt);
l = far[f1];
f1 = top[l];
}
if(l == r)
return tt;
if(dep[l] > dep[r]) swap(l,r);
return max(tt,query(1,p[son[l]],p[r]));
} void change(int l,int r)
{
int f1 = top[l];
int f2 = top[r];
while(f1 != f2)
{
if(dep[f1] < dep[f2])
{
swap(f1,f2);
swap(l,r);
}
negat(1,p[f1],p[l]);
l = far[f1];
f1 = top[l];
}
if(l == r) return ;
if(dep[l] > dep[r]) swap(l,r);
negat(1,p[son[l]],p[r]);
} void ini()
{
tot = 0;
pos = 1;
memset(head,-1,sizeof(head));
memset(son,-1,sizeof(son));
} int me[maxn][2];
int va[maxn]; int main()
{
int T;
int n;
//freopen("in.txt","r",stdin);
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
ini();
for(int i = 1; i < n; i++)
{
scanf("%d%d%d",&me[i][0],&me[i][1],&va[i]);
addedge(me[i][0],me[i][1]);
addedge(me[i][1],me[i][0]);
} dfs(1,0,0);
getpos(1,1);
build(1,1,n);
for(int i = 1; i < n; i++)
{
if(dep[me[i][0]] > dep[me[i][1]])
swap(me[i][0],me[i][1]);
update(1,p[me[i][1]],va[i]);
}
char ch[10];
while(scanf("%s",ch) == 1)
{
;
if(ch[0] == 'D') break;
int u,v;
scanf("%d%d",&u,&v);
if(ch[0] == 'Q')
printf("%d\n",fin(u,v));
else if(ch[0] == 'N')
change(u,v);
else
update(1,p[me[u][1]],v);
}
}
return 0;
}

  

poj3237 树链部分 边权模板的更多相关文章

  1. 树链剖分边权模板spoj375

    树链剖分是树分解成多条链来解决树上两点之间的路径上的问题 如何求出树链:第一次dfs求出树上每个结点的大小和深度和最大的儿子,第二次dfs就能将最大的儿子串起来并hash(映射)到线段树上(或者其他数 ...

  2. poj3237树链剖分边权+区间取负

    树链剖分+线段树lazy-tag在树链上操作时千万不要写错.. /* 树链剖分+线段树区间变负 */ #include<iostream> #include<cstring> ...

  3. hdu3966 树链剖分点权模板+线段树区间更新/树状数组区间更新单点查询

    点权树的模板题,另外发现树状数组也是可以区间更新的.. 注意在对链进行操作时方向不要搞错 线段树版本 #include<bits/stdc++.h> using namespace std ...

  4. POJ3237 Tree 树链剖分 边权

    POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...

  5. 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)

    Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...

  6. BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分 - 点权剖分 - 单点权修改)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1036 树链剖分模版题,打的时候注意点就行.做这题的时候,真的傻了,单词拼错检查了一个多小时 ...

  7. POJ2763 Housewife Wind 树链剖分 边权

    POJ2763 Housewife Wind 树链剖分 边权 传送门:http://poj.org/problem?id=2763 题意: n个点的,n-1条边,有边权 修改单边边权 询问 输出 当前 ...

  8. HDU3669 Aragorn's Story 树链剖分 点权

    HDU3669 Aragorn's Story 树链剖分 点权 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意: n个点的,m条边,每个点都 ...

  9. 洛谷 P3384 【模板】树链剖分-树链剖分(点权)(路径节点更新、路径求和、子树节点更新、子树求和)模板-备注结合一下以前写的题目,懒得写很详细的注释

    P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...

随机推荐

  1. python网络爬虫,知识储备,简单爬虫的必知必会,【核心】

    知识储备,简单爬虫的必知必会,[核心] 一.实验说明 1. 环境登录 无需密码自动登录,系统用户名shiyanlou 2. 环境介绍 本实验环境采用带桌面的Ubuntu Linux环境,实验中会用到桌 ...

  2. 泛型的 typeof

    static void Main(string[] args) { TestTypeOf<string>(); Console.ReadKey(); } static void TestT ...

  3. 阿里云API网关(7)开发指南-API参考

    网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...

  4. HTTP协议扫盲(三)HTTP协议的请求头列表和分类描述

    一.请求报头和响应报头列表 1.Requests 头列表 Header 解释 示例 Accept 指定客户端能够接收的内容类型 Accept: text/plain, text/html Accept ...

  5. C#微信公众号开发——access_token的获取

    access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token.正常情况下access_token有效期为7200秒,重复获取将导致上次获取的access_toke ...

  6. C++中explicit关键字

    explicit: 防止隐式转换使用. 隐式转换:不同类型的变量可以互相转换,如将一个整形数值赋值给一个类,ClassXX  lei = 4: C++中, 一个参数的构造函数(或者除了第一个参数外其余 ...

  7. 浅析开源数据库MySQL架构

    数据库是所有应用系统的核心,故保证数据库稳定.高效.安全地运行是所有企业日常工作的重中之重.数据库系统一旦出现问题无法提供服务,有可能导致整个系统都无法继续工作.所以,一个成功的数据库架构在高可用设计 ...

  8. scrapy spider官方文档

    Spiders Spider类定义了如何爬取某个(或某些)网站.包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item). 换句话说,Spider就是您定义爬取的动作 ...

  9. Checkbutton

    #tkinter之Checkbutton篇 #Checkbutton又称为多选按钮,可以表示两种状态,On和Off,可以设置回调函数,每当点击此按钮时回调函数被调用. 1.一个简单的Checkbutt ...

  10. Git篇(基础)

    安装过程省略... 至于安装目录的有关功能,略过... 一.关于初次使用的关键配置命令: 1.配置基本信息,该信息将保存在该用户目录下的.gitconfig文件内 配置用户信息$ git config ...