poj3237 树链部分 边权模板
| 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 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
/*
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 树链部分 边权模板的更多相关文章
- 树链剖分边权模板spoj375
树链剖分是树分解成多条链来解决树上两点之间的路径上的问题 如何求出树链:第一次dfs求出树上每个结点的大小和深度和最大的儿子,第二次dfs就能将最大的儿子串起来并hash(映射)到线段树上(或者其他数 ...
- poj3237树链剖分边权+区间取负
树链剖分+线段树lazy-tag在树链上操作时千万不要写错.. /* 树链剖分+线段树区间变负 */ #include<iostream> #include<cstring> ...
- hdu3966 树链剖分点权模板+线段树区间更新/树状数组区间更新单点查询
点权树的模板题,另外发现树状数组也是可以区间更新的.. 注意在对链进行操作时方向不要搞错 线段树版本 #include<bits/stdc++.h> using namespace std ...
- POJ3237 Tree 树链剖分 边权
POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...
- 计蒜客 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 ...
- BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分 - 点权剖分 - 单点权修改)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1036 树链剖分模版题,打的时候注意点就行.做这题的时候,真的傻了,单词拼错检查了一个多小时 ...
- POJ2763 Housewife Wind 树链剖分 边权
POJ2763 Housewife Wind 树链剖分 边权 传送门:http://poj.org/problem?id=2763 题意: n个点的,n-1条边,有边权 修改单边边权 询问 输出 当前 ...
- HDU3669 Aragorn's Story 树链剖分 点权
HDU3669 Aragorn's Story 树链剖分 点权 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意: n个点的,m条边,每个点都 ...
- 洛谷 P3384 【模板】树链剖分-树链剖分(点权)(路径节点更新、路径求和、子树节点更新、子树求和)模板-备注结合一下以前写的题目,懒得写很详细的注释
P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...
随机推荐
- pandas 使用
ss = [['xx','m',22],['cc','w',33],['jj','w',44],['qq','m',11]] import pandas as pd df = pd.DataFrame ...
- 怎么去理解JAVA中类与对象的关系
首先要明确,在现实生活中,每一个物体都有自己的基本特征,专业一点也可以说成是属性有些甚至还有一定的行为.例如 汽车的特征:有车门.有轮胎.颜色各一等等,行为:有行驶,开车门,开车灯,等等.有这些属性和 ...
- codevs 3981 动态最大子段和
3981 动态最大子段和 http://codevs.cn/problem/3981/ 题目等级 : 钻石 Diamond 题目描述 Description 题目还是简单一点好... 有n个 ...
- python端口扫描用多线程+线程安全的队列+Thread类实现
用线程安全的队列Queue实现扫描端口数据存储 用多线程扫描端口 用Thread类实现程序组织 #coding:utf-8 import sys import socket import sys im ...
- linux的slect的脚本适用于交互
[rhuang@localhost ~]$ vi os.sh #!/bin/bash echo "What is your favourite OS?" select var in ...
- Python内置函数(49)——isinstance
英文文档: isinstance(object, classinfo) Return true if the object argument is an instance of the classin ...
- maven构建spring报错org.springframework.core.NestedRuntimeException cannot be resolved.
Error:The type org.springframework.core.NestedRuntimeException cannot be resolved. It is indirectly ...
- SpringBoot的配置文件加载顺序和使用方式
1.bootstrap.properties bootstrap.properties 配置文件是由"根"上下文优先加载,程序启动之初就感知 如:Spring Cloud Conf ...
- 前端之BOM和DOM
BOM和DOM简介 BOM(Browser Object Model)是指浏览器对象模型,它使JavaScript有能力与浏览器进行“对话”. DOM(Document Object Model)是指 ...
- kafka知识体系
最近一直在整理kafka相关资料,以构建自己的知识体系. 主要分为五大方面: Kafka设计与原理分析 Kafka配置分析 Kafka运维手册 Kafka编程开发 kafka源码分析