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. Android实验报告

    实验名称:Android程序设计 实验时间:2017.5.24 实验人员:20162309邢天岳(结对同学20162313苑洪铭) 实验目的:使用android stuidio开发工具进行基本安卓软件 ...

  2. mui 页面无法下滑拖拽 主要体现在华为手机浏览器

    项目做到中期遇到一个问题,华为手机有些页面显示不全且无法下滑. 因为之前一直用的Google浏览器的模拟模式进行开发和调试的,一直未发现这个问题. 刚开始 选用mui的下拉刷新上拉加载的方式来进行页面 ...

  3. 测试驱动开发实践3————从testList开始

    [内容指引] 运行单元测试: 装配一条数据: 模拟更多数据测试列表: 测试无搜索列表: 测试标准查询: 测试高级查询. 一.运行单元测试 我们以文档分类(Category)这个领域类为例,示范如何通过 ...

  4. Full-Stack-Fundation-Udacity------Lesson 1 Working with CRUD

    因为手头在做一个项目,我负责后台,就顺带快进学习Udacity上一个水课(?):Full Stack Foundation.上课的好像是个印度小哥(?),按1.5倍速听讲话还是有点逗的.废话不多说,进 ...

  5. FTP传输文件被破坏的问题(Linux、Busybox)

    在网络设备上抓包后,通过FTP传输到本机,发现抓包文件破坏.更换tftp后文件正常,定位问题在FTP上. FTP的传输模式有两种:①ASCII  ②二进制 ①ASCII: 以ASCII编码的方式传输文 ...

  6. jQuery兼容浏览器IE8方法

    在维护公司网站的时候,发现在IE8下jquery会报对象不支持此属性或方法.缺少对象的错误:  在其他浏览器就可以正常运行,当前使用的jquery版本是3.1.1,查资料发现jquery从2.0开始不 ...

  7. Python-面向对象(二)-Day7

    1.字段 12.方法 43.属性 63.1.属性的基本使用 73.2.实例:对于主机列表 83.3.属性的两种定义方式 94.对于类的成员而言都有两种形式: 144.1.私有成员和公有成员的访问限制不 ...

  8. 新概念英语(1-5)Nice to meet you.

    Is Chang-woo Chinese? Blake:Good morning. B:Good morning, Mr Blake. Blake:This is Miss Sophie Dupont ...

  9. Ajax实现注册无刷新验证用户名是否存在

    1. [代码][JavaScript]代码     ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 ...

  10. Microsoft CRM-QueryExpression 成员

      名称 ColumnSet 获取或设置要包含的列. Criteria 获取或设置过滤查询结果的复杂条件和逻辑过滤器表达式. Distinct 获取或设置查询的结果是否包含重复的实体实例. Entit ...