树链剖分+线段树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字典遍历的几种方法

    (1)遍历key值 >>> a {'} >>> for key in a: print(key+':'+a[key])   a:1 b:2 c:3 >> ...

  2. Swagger介绍-一套流行的API框架

    简介 号称:世界最流行的API框架 官网:http://swagger.io/ 解决什么问题:在前后台分离的开发模式中,减小接口定义沟通成本,方便开发过程中测试,自动生成接口文档. 实例代码位置:ht ...

  3. GoLang基础数据类型--->字符串处理大全

    GoLang基础数据类型--->字符串处理大全 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 欢迎加入:   高级运维工程师之路               59843264 ...

  4. collectd使用

    1.什么是collectd collectd是一款基于C语言研发的插件式架构的监控软件,它可以收集各种来源的指标,如操作系统,应用程序,日志文件和外部设备,并存储此信息或通过网络提供.这些统计数据可用 ...

  5. 神级程序员通过两句话带你完全掌握Python最难知识点——元类!

    千万不要被所谓"元类是99%的python程序员不会用到的特性"这类的说辞吓住.因为 每个中国人,都是天生的元类使用者 学懂元类,你只需要知道两句话: 道生一,一生二,二生三,三生 ...

  6. python学习笔记9--日志模块logging

    我们在写程序的时候经常会打一些日志来帮助我们查找问题,这次学习一下logging模块,在python里面如何操作日志.介绍一下logging模块,logging模块就是python里面用来操作日志的模 ...

  7. Python基础(函数部分)-day04

    写在前面 上课第四天,打卡: 加勒比海盗今天上映:端午节公司发的粽子很有范! 一.函数的基本概念 - 函数是什么?  函数,就是一个'锤子',一个具有特定功能的'锤子',使用者可以在适当的时候使用这个 ...

  8. C# 窗体最大化(自适应任务栏位置)

    this.FormBorderStyle = FormBorderStyle.None; this.Location=Screen.PrimaryScreen.WorkingArea.Location ...

  9. springboot使用elasticsearch报No property index found for type错误

    一.前提:项目之前使用springboot+spring-data-mongodb.现在需要加入elasticsearch做搜索引擎,这样mongo和elasticsearch共存了. 二.报错信息: ...

  10. JavaScript之从浏览器一键获取教务处个人课程信息【插件】

    由于博主的个人网站(:http://www.johnnyzen.cn/),每学期都需要更新呈现课程的静态信息,由于课程量多,而且手动爬取很冗杂,特别想自动化实现.这不,今天终于有点时间了,把之前写no ...