树链剖分+线段树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. Python Machine Learning-Chapter3

    Chapter 3:A Tour of Machine Learning Classifiers Using Scikit-learn 3.1:Training a perceptron via sc ...

  2. UDP网路会议室的代码

    UDP网络会议室视频已经录制好,这里贴上代码仅供参考 MainWindow代码: using System; using System.Collections.Generic; using Syste ...

  3. 标准遗传算法(实数编码 python实现)模拟二进制交叉SBX 多项式变异

    代码地址: https://github.com/guojun007/real_sga 本部分是采用实数编码的标准遗传算法,整体流程与上一篇二进制编码的基本一致, 主要区别在于本部分的交叉操作为模拟二 ...

  4. Hadoop记录-MRv2(Yarn)运行机制

    1.MRv2结构—Yarn模式运行机制 Client---客户端提交任务 ResourceManager---资源管理 ---Scheduler调度器-资源分配Containers ----在Yarn ...

  5. js格式化input输入框内容(每几位分一组,并使用特定字符分隔)

    <html> <head> <title></title> </head> <body> <input id=" ...

  6. BIO | NIO | AIO (Java版)

    几篇解释的不错的文章: BIO NIO AIO NIO.2 入门,第 1 部分: 异步通道 API 使用异步 I/O 大大提高应用程序的性能

  7. 怎样动态地插入不会暴露给用户的JS文件

    也是无意间看见的,以前想过这个问题,但是没多想,今天看到这段代码豁然开朗 (function() { var dynamicScript = document.createElement('scrip ...

  8. Nginx 日志处理

    . nginx日志统计独立ip的个数: awk '{print $1}' /access.log | sort | uniq | wc -l . 查询访问最多的前10个ip awk . 查看某段时间的 ...

  9. 字体选择框QFontComboBox

    self.combobox_2 = QFontComboBox(self)  # 实例化字体列表框 combobox.currentFont()  返回字体选择框中当前的字体 self.combobo ...

  10. HTML5的学习(三)HTML5标签

    3.HTML5新添加的标签 标签 描述 <article> 定义文章. <aside> 定义页面内容之外的内容. <audio> 定义声音内容. <bdi&g ...