树链剖分+线段树lazy-tag
在树链上操作时千万不要写错。。

/*
树链剖分+线段树区间变负
*/
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define maxn 10005
struct Edge{
int to,next;
}edge[maxn<<];
int head[maxn],tot,e[maxn][];
int fa[maxn],son[maxn],num[maxn],deep[maxn];
int top[maxn],fp[maxn],p[maxn],pos;
inline void addedge(int u,int v){
edge[tot].to=v;edge[tot].next=head[u];head[u]=tot++;
}
void dfs1(int u,int pre,int dep){
fa[u]=pre;num[u]=;deep[u]=dep;
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].to;
if(v==pre) continue;
dfs1(v,u,dep+);
num[u]+=num[v];
if(son[u]==- || num[son[u]]<num[v]) son[u]=v;
}
}
void getpos(int u,int sp){
top[u]=sp;p[u]=pos++;fp[p[u]]=u;
if(son[u]==-) return;
getpos(son[u],sp);
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].to;
if(v!=fa[u] && v!=son[u]) getpos(v,v);
}
} #define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int Max[maxn<<],Min[maxn<<],rev[maxn<<];//遇到区间取反的通常维护一下区间两个极值
void build(int l,int r,int rt){
Max[rt]=Min[rt]=rev[rt]=;
if(l==r) return;
int m=l+r>>;
build(lson);build(rson);
}
inline void pushup(int rt){
Max[rt]=max(Max[rt<<],Max[rt<<|]);
Min[rt]=min(Min[rt<<],Min[rt<<|]);
}
inline void pushdown(int rt){
if(rev[rt]){
rev[rt<<]^=,rev[rt<<|]^=;
swap(Min[rt<<],Max[rt<<]);
Min[rt<<]*=-,Max[rt<<]*=-;
swap(Min[rt<<|],Max[rt<<|]);
Min[rt<<|]*=-,Max[rt<<|]*=-;
rev[rt]=;
}
}
void update(int pos,int val,int l,int r,int rt){
if(l==r){Max[rt]=Min[rt]=val;rev[rt]=;return;}
int m=l+r>>;
pushdown(rt);
if(pos<=m) update(pos,val,lson);
else update(pos,val,rson);
pushup(rt);
}
void seg_negate(int L,int R,int l,int r,int rt){
if(L<=l && R>=r){
swap(Min[rt],Max[rt]);
Min[rt]*=-,Max[rt]*=-;
rev[rt]^=;
return;
}
pushdown(rt);
int m=l+r>>;
if(L<=m) seg_negate(L,R,lson);
if(R>m) seg_negate(L,R,rson);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt){
if(L<=l && R>=r)return Max[rt];
pushdown(rt);
int m=l+r>>,res=-;
if(L<=m) res=max(res,query(L,R,lson));
if(R>m) res=max(res,query(L,R,rson));
pushup(rt);
return res;
}
int find(int u,int v)//查询u->v边的最大值
{
int f1 = top[u], f2 = top[v];
int tmp = -;
while(f1 != f2)
{
if(deep[f1] < deep[f2])
{
swap(f1,f2);
swap(u,v);
}
tmp = max(tmp,query(p[f1],p[u],,pos,));
u = fa[f1]; f1 = top[u];
}
if(u == v)return tmp;
if(deep[u] > deep[v]) swap(u,v);
return max(tmp,query(p[son[u]],p[v],,pos,));
}
void Negate(int u,int v)//把u-v路径上的边的值都设置为val
{
int f1 = top[u], f2 = top[v];
while(f1 != f2)
{
if(deep[f1] < deep[f2])
{
swap(f1,f2);
swap(u,v);
}
seg_negate(p[f1],p[u],,pos,);
u = fa[f1]; f1 = top[u];
}
if(u == v)return;
if(deep[u] > deep[v]) swap(u,v);
return seg_negate(p[son[u]],p[v],,pos,);
}
void init(){
tot=pos=;
memset(head,-,sizeof head);
memset(son,-,sizeof son);
}
int main(){
int T,n,a,b,c;
char op[];
cin >> T;
while(T--){
init();
scanf("%d",&n);
for(int i=;i<=n-;i++){
scanf("%d%d%d",&e[i][],&e[i][],&e[i][]);
addedge(e[i][],e[i][]);addedge(e[i][],e[i][]);
}
dfs1(,,);getpos(,);build(,pos,);
for(int i=;i<=n-;i++){
if(deep[e[i][]]>deep[e[i][]]) swap(e[i][],e[i][]);
update(p[e[i][]],e[i][],,pos,);
} while(scanf("%s",op)){
if(op[]=='D') break;
scanf("%d%d",&a,&b);
if(op[]=='C')update(p[e[a][]],b,,pos,);
else if(op[]=='N') Negate(a,b);
else printf("%d\n",find(a,b));
}
}
}

poj3237树链剖分边权+区间取负的更多相关文章

  1. poj2763树链剖分边权+区间和

    自己写的比原来的板子常数小了不少嘻嘻,边权处理起来比点权要复杂一下 由于根节点没有被映射的边,其被访问到的顺序是0,直接排除在线段树外 #include<iostream> #includ ...

  2. POJ3237 Tree 树链剖分 边权

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

  3. 计蒜客 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 ...

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

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

  5. POJ2763 Housewife Wind 树链剖分 边权

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

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

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

  7. POJ 3237.Tree -树链剖分(边权)(边值更新、路径边权最值、区间标记)贴个板子备忘

    Tree Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 12247   Accepted: 3151 Descriptio ...

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

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

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

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

随机推荐

  1. wget一个网站很慢的原因

    今天wget一个网站时,发现很慢: # wget www.baidu.com ---- ::-- http://www.baidu.com/ Resolving www.baidu.com... 14 ...

  2. selenium_基本用法

    Python爬虫视频教程零基础小白到scrapy爬虫高手-轻松入门 https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.482434a6E ...

  3. CodeChef - CRYPCUR

    题目链接 AMRExchange is the latest cryptocurrency exchange that has become very popular among cryptocurr ...

  4. 关于javaBean,pojo,EJB

    JavaBean是公共Java类 1.所有属性为private.2.提供默认无参构造方法.3.类属性通过getter和setter操作.4.实现serializable接口.

  5. 浅谈分词算法(4)基于字的分词方法(CRF)

    目录 前言 目录 条件随机场(conditional random field CRF) 核心点 线性链条件随机场 简化形式 CRF分词 CRF VS HMM 代码实现 训练代码 实验结果 参考文献 ...

  6. JAVA实现二叉树(简易版--实现了二叉树的各种遍历)

    1,个人感觉二叉树的实现主要还是如何构造一颗二叉树.构造二叉树函数的设计方法多种多样,本例采用 addNode 方法实现.以下程序通过定义内部类来表示二叉树的结点,然后再实现了二叉树这种数据结构的一些 ...

  7. 六、uboot 代码流程分析---start.S

    6.1 _start 入口函数 6.1.1 vectors.S (arch\arm\lib) 从上一节可以知道,uboot 的入口函数为 _start .此 函数定义在 vectors.S (arch ...

  8. mongoDB - 日常操作三

    MongoDB 进程控制 进程控制 db.currentOp() # 查看活动进程 db.$cmd.sys.inprog.findOne() # 查看活动进程 与上面一样 opid # 操作进程号 o ...

  9. luogu P2325 [SCOI2005]王室联邦

    传送门 做法是dfs整棵树,当访问一个点\(x\)时,先访问儿子,若某个时刻子树大小\(\ge b\)时,就把那些点放在一个省里,省会记为\(x\),访问完儿子再把\(x\)加入栈.最后栈中剩余的没加 ...

  10. 2016年1月7日 隐藏NavigationBar时的一个坑

    http://www.jianshu.com/p/efb960fed457 - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear: ...