BZOJ 2157 旅行(树链剖分码农题)
写了5KB,1发AC。。。
题意:给出一颗树,支持5种操作。
1.修改某条边的权值。2.将u到v的经过的边的权值取负。3.求u到v的经过的边的权值总和。4.求u到v的经过的边的权值最大值。5.求u到v经过的边的权值最小值。
基于边权的树链剖分,放在线段树上变成了区间维护问题了,线段树维护4个量min,max,sum,tag就可以了。
# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <bitset>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
const int N=;
//Code begin... struct Edge{int p, next;}edge[N<<];
struct Seg{int sum, ma, mi;}seg[N<<];
bool tag[N<<];
int head[N], cnt=, E[N][], n;
int top[N], fa[N], deep[N], num[N], p[N], fp[N], son[N], pos; void add_edge(int u, int v){
edge[cnt].p=v; edge[cnt].next=head[u]; head[u]=cnt++;
}
void init(){mem(son,-); pos=;}
void dfs1(int u, int pre, int d){
deep[u]=d; fa[u]=pre; num[u]=;
for (int i=head[u]; i; i=edge[i].next) {
int v=edge[i].p;
if (v==pre) continue;
dfs1(v,u,d+); num[u]+=num[v];
if (son[u]==-||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]==-) return ;
getpos(son[u],sp);
for (int i=head[u]; i; i=edge[i].next) {
int v=edge[i].p;
if (v!=son[u]&&v!=fa[u]) getpos(v,v);
}
}
void push_up(int p){
seg[p].sum=seg[p<<].sum+seg[p<<|].sum;
seg[p].ma=max(seg[p<<].ma,seg[p<<|].ma);
seg[p].mi=min(seg[p<<].mi,seg[p<<|].mi);
}
void push_down(int p){
if (!tag[p]) return ;
seg[p].sum=-seg[p].sum; swap(seg[p].ma,seg[p].mi); seg[p].ma=-seg[p].ma; seg[p].mi=-seg[p].mi;
tag[p<<]^=tag[p]; tag[p<<|]^=tag[p]; tag[p]=false;
}
void Update(int p, int l, int r, int L, int val){
push_down(p);
if (L>r||L<l) return ;
if (L==l&&L==r) seg[p].ma=seg[p].mi=seg[p].sum=val;
else {
int mid=(l+r)>>;
Update(lch,L,val); Update(rch,L,val); push_up(p);
}
}
void Inv(int p, int l, int r, int L, int R){
push_down(p);
if (L>r||R<l) return ;
if (L<=l&&R>=r) tag[p]^=, push_down(p);
else {
int mid=(l+r)>>;
Inv(lch,L,R); Inv(rch,L,R); push_up(p);
}
}
int Query_Max(int p, int l, int r, int L, int R){
push_down(p);
if (L>r||R<l) return -INF;
if (L<=l&&R>=r) return seg[p].ma;
int mid=(l+r)>>;
return max(Query_Max(lch,L,R),Query_Max(rch,L,R));
}
int Query_Min(int p, int l, int r, int L, int R){
push_down(p);
if (L>r||R<l) return INF;
if (L<=l&&R>=r) return seg[p].mi;
int mid=(l+r)>>;
return min(Query_Min(lch,L,R),Query_Min(rch,L,R));
}
int Query_Sum(int p, int l, int r, int L, int R){
push_down(p);
if (L>r||R<l) return ;
if (L<=l&&R>=r) return seg[p].sum;
int mid=(l+r)>>;
return Query_Sum(lch,L,R)+Query_Sum(rch,L,R);
}
int Sol(int u, int v, int flag){
int f1=top[u], f2=top[v], ans;
if (flag==) ans=;
else if (flag==) ans=-INF;
else ans=INF;
while (f1!=f2) {
if (deep[f1]<deep[f2]) swap(f1,f2), swap(u,v);
if (flag==) Inv(,,n,p[f1],p[u]);
else if (flag==) ans+=Query_Sum(,,n,p[f1],p[u]);
else if (flag==) ans=max(ans,Query_Max(,,n,p[f1],p[u]));
else ans=min(ans,Query_Min(,,n,p[f1],p[u]));
u=fa[f1]; f1=top[u];
}
if (u==v) return ans;
if (deep[u]>deep[v]) swap(u,v);
if (flag==) {Inv(,,n,p[son[u]],p[v]); return ;}
else if (flag==) return ans+Query_Sum(,,n,p[son[u]],p[v]);
else if (flag==) return max(ans,Query_Max(,,n,p[son[u]],p[v]));
else return min(ans,Query_Min(,,n,p[son[u]],p[v]));
}
int main ()
{
int m, x, y;
char s[];
scanf("%d",&n); init();
FO(i,,n) scanf("%d%d%d",&E[i][],&E[i][],&E[i][]), ++E[i][], ++E[i][], add_edge(E[i][],E[i][]), add_edge(E[i][],E[i][]);
dfs1(,,); getpos(,);
FO(i,,n) {
if (deep[E[i][]]>deep[E[i][]]) swap(E[i][],E[i][]);
Update(,,n,p[E[i][]],E[i][]);
}
scanf("%d",&m);
while (m--) {
scanf("%s%d%d",s,&x,&y);
if (!strcmp(s,"C")) Update(,,n,p[E[x][]],y);
else if (!strcmp(s,"N")) ++x, ++y, Sol(x,y,);
else if (!strcmp(s,"SUM")) ++x, ++y, printf("%d\n",Sol(x,y,));
else if (!strcmp(s,"MAX")) ++x, ++y, printf("%d\n",Sol(x,y,));
else ++x, ++y, printf("%d\n",Sol(x,y,));
}
return ;
}
BZOJ 2157 旅行(树链剖分码农题)的更多相关文章
- BZOJ 2157: 旅游( 树链剖分 )
树链剖分.. 样例太大了根本没法调...顺便把数据生成器放上来 -------------------------------------------------------------------- ...
- BZOJ 2157: 旅游 (树链剖分+线段树)
树链剖分后线段树维护区间最大最小值与和. 支持单点修改与区间取反. 直接写个区间取反标记就行了.线段树板题.(200行6000B+ 1A警告) #include <cstdio> #inc ...
- BZOJ.3531.旅行(树链剖分 动态开点)
题目链接 无优化版本(170行): /* 首先树剖可以维护树上的链Sum.Max 可以对每个宗教建一棵线段树,那这题就很好做了 不过10^5需要动态开点 (不明白为什么nlogn不需要回收就可以 不是 ...
- BZOJ 2243 染色 | 树链剖分模板题进阶版
BZOJ 2243 染色 | 树链剖分模板题进阶版 这道题呢~就是个带区间修改的树链剖分~ 如何区间修改?跟树链剖分的区间询问一个道理,再加上线段树的区间修改就好了. 这道题要注意的是,无论是线段树上 ...
- BZOJ 3083 遥远的国度 树链剖分+线段树
有换根的树链剖分的裸题. 在换根的时候注意讨论. 注意数据范围要开unsigned int或longlong #include<iostream> #include<cstdio&g ...
- BZOJ 3531 [Sdoi2014]旅行 树链剖分+动态开点线段树
题意 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. 为了方便,我们用 ...
- BZOJ 3531: [Sdoi2014]旅行 [树链剖分]
3531: [Sdoi2014]旅行 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1685 Solved: 751[Submit][Status] ...
- BZOJ 3531 SDOI2014 旅行 树链剖分+线段树动态开点
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3531 题意概述: 给出一棵N个点的树,树上的每个结点有一个颜色和权值,支持以下四种操作: ...
- BZOJ3531:[SDOI2014]旅行(树链剖分)
Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足 从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰 ...
随机推荐
- # 20155327 2016-20017-3 《Java程序设计》第3周学习总结
教材学习内容总结 第四章 认识对象 区分基本类型与类类型 基本类型: 1.整数:包括int,short,byte,long ,初始值为0 2.浮点型:float,double ,初始值为0.0 3.字 ...
- 【原创】user.id字段
odoo中User.ID 字段是用户登录表 res_users 中的字段,所以要关联某个用户或是判断某个用户,可以利用该字段. 例如:在某个 界面中的domain中,要求显示的是关联某用户的单子,则如 ...
- 运行ntpdate报错:Temporary failure in name resolution
一.问题报错: 忽然发现某台机器时间慢了些几分钟,之前没有搭建ntpd服务,目前都是使用的ntpdate加定时任务进行时间同步.直接执行ntpdate报错如下: # ntpdate cn.pool.n ...
- 提取oracle awr报告
做性能测试时有时需要分析sql的执行情况,以找出需要优化的sql,oracle数据库就提供了很好的数据库状态和sql执行情况的监控平台,数据库的监控平台可以时时的监控数据库的状态,同时还可以取监控的时 ...
- Maven学习(十一)-----使用Maven创建Web应用程序项目
使用Maven创建Web应用程序项目 用到的技术/工具: Maven 3.3.3 Eclipse 4.3 JDK 8 Spring 4.1.1.RELEASED Tomcat 7 Logback 1. ...
- 基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(上)
最近接触过几个版本的cocos2dx,决定每个大变动的版本都尝试一下.本实例模仿微信5.0版本中的飞机大战游戏,如图: 一.工具 1.素材:飞机大战的素材(图片.声音等)来自于网络 2.引擎:coco ...
- SQL Server 2008 R2 链接 Oracle 10g
首先sqlserver 链接oracle可以通过两个访问接口: “MSDAORA” 和“OraOLEDB.Oracle” 1.“MSDAORA”访问接口是由Microsoft OLE DB Provi ...
- 学习HTML 第三节.接近正题:HTML样式-CSS级联样式表
CSS (Cascading Style Sheets)级联样式表 内联样式 内联样式- 在HTML元素中使用"style" 属性 使用内联样式的方法是在相关的标签中使用样式属性. ...
- mnist手写数字识别(神经网络)
import numpy as np from sklearn.neural_network import MLPClassifier path = 'mnist.npz' f = np.load(p ...
- 【Python 开发】Python目录
目录: [Python开发]第一篇:计算机基础 [Python 开发]第二篇 :Python安装 [Python 开发]第三篇:python 实用小工具