洛谷P1505 [国家集训队]旅游(树剖+线段树)
这该死的码农题……
把每一条边变为它连接的两个点中深度较浅的那一个,然后就是一堆单点修改/路径查询,不讲了
这里就讲一下怎么搞路径取反,只要打一个标记就好了,然后把区间和取反,最大最小值交换然后再取反
单点修改的时候忘记pushdown结果调了好久……
//minamoto
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,:;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,:;}
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getchar()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getchar());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char sr[<<],z[];int K=-,Z;
inline void Ot(){fwrite(sr,,K+,stdout),K=-;}
inline void print(int x){
if(K><<)Ot();if(x<)sr[++K]=,x=-x;
while(z[++Z]=x%+,x/=);
while(sr[++K]=z[Z],--Z);sr[++K]='\n';
}
const int N=;
int head[N],Next[N<<],ver[N<<],edge[N<<],tot=;
inline void add(int u,int v,int e){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
}
int dfn[N],top[N],sz[N],son[N],num[N],val[N],dep[N],fa[N],cnt,n,m;
void dfs1(int u){
sz[u]=,dep[u]=dep[fa[u]]+;
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v!=fa[u]){
fa[v]=u,num[i>>]=v,dfs1(v),sz[u]+=sz[v];
if(sz[son[u]]<sz[v]) son[u]=v;
}
}
}
void dfs2(int u,int t){
top[u]=t,dfn[u]=++cnt;
if(son[u]){
dfs2(son[u],t);
for(int i=head[u];i;i=Next[i])
if(ver[i]!=fa[u]&&ver[i]!=son[u])
dfs2(ver[i],ver[i]);
}
}
int mx[N<<],mn[N<<],sum[N<<],rev[N<<];
#define ls (p<<1)
#define rs (p<<1|1)
inline void upd(int p){
mx[p]=max(mx[ls],mx[rs]),mn[p]=min(mn[ls],mn[rs]),sum[p]=sum[ls]+sum[rs];
}
inline void ppd(int p){
rev[p]^=,sum[p]=-sum[p],swap(mn[p],mx[p]),mn[p]=-mn[p],mx[p]=-mx[p];
}
inline void pd(int p){
if(rev[p]){
ppd(ls),ppd(rs);
rev[p]=;
}
}
void build(int p,int l,int r){
if(l==r) return (void)(mx[p]=mn[p]=sum[p]=val[l]);
int mid=(l+r)>>;
build(ls,l,mid),build(rs,mid+,r);
upd(p);
}
void update(int p,int l,int r,int x){
if(l==r) return (void)(mn[p]=mx[p]=sum[p]=val[l]);
int mid=(l+r)>>;pd(p);
x<=mid?update(ls,l,mid,x):update(rs,mid+,r,x);
upd(p);
}
void Rev(int p,int l,int r,int ql,int qr){
if(ql<=l&&qr>=r) return (void)(ppd(p));
int mid=(l+r)>>;pd(p);
if(ql<=mid) Rev(ls,l,mid,ql,qr);
if(qr>mid) Rev(rs,mid+,r,ql,qr);
upd(p);
}
int querysum(int p,int l,int r,int ql,int qr){
if(ql<=l&&qr>=r) return sum[p];
int mid=(l+r)>>,res=;pd(p);
if(ql<=mid) res+=querysum(ls,l,mid,ql,qr);
if(qr>mid) res+=querysum(rs,mid+,r,ql,qr);
return res;
}
int querymax(int p,int l,int r,int ql,int qr){
if(ql<=l&&qr>=r) return mx[p];
int mid=(l+r)>>,res=-inf;pd(p);
if(ql<=mid) cmax(res,querymax(ls,l,mid,ql,qr));
if(qr>mid) cmax(res,querymax(rs,mid+,r,ql,qr));
return res;
}
int querymin(int p,int l,int r,int ql,int qr){
if(ql<=l&&qr>=r) return mn[p];
int mid=(l+r)>>,res=inf;pd(p);
if(ql<=mid) cmin(res,querymin(ls,l,mid,ql,qr));
if(qr>mid) cmin(res,querymin(rs,mid+,r,ql,qr));
return res;
}
void change(int i,int x){
val[dfn[num[i]]]=x,update(,,n,dfn[num[i]]);
}
void RRR(int u,int v){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
Rev(,,n,dfn[top[u]],dfn[u]);u=fa[top[u]];
}
if(u!=v){
if(dep[u]<dep[v]) swap(u,v);
Rev(,,n,dfn[son[v]],dfn[u]);
}
}
int SUM(int u,int v){
int res=;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
res+=querysum(,,n,dfn[top[u]],dfn[u]);u=fa[top[u]];
}
if(u!=v){
if(dep[u]<dep[v]) swap(u,v);
res+=querysum(,,n,dfn[son[v]],dfn[u]);
}
return res;
}
int MAX(int u,int v){
int res=-inf;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
cmax(res,querymax(,,n,dfn[top[u]],dfn[u]));u=fa[top[u]];
}
if(u!=v){
if(dep[u]<dep[v]) swap(u,v);
cmax(res,querymax(,,n,dfn[son[v]],dfn[u]));
}
return res;
}
int MIN(int u,int v){
int res=inf;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
cmin(res,querymin(,,n,dfn[top[u]],dfn[u]));u=fa[top[u]];
}
if(u!=v){
if(dep[u]<dep[v]) swap(u,v);
cmin(res,querymin(,,n,dfn[son[v]],dfn[u]));
}
return res;
}
char s[];
int main(){
// freopen("testdata.in","r",stdin);
n=read();
for(int i=,u,v,e;i<n;++i)
u=read()+,v=read()+,e=read(),add(u,v,e),add(v,u,e);
dfs1(),dfs2(,);
for(int i=;i<n;++i) val[dfn[num[i]]]=edge[i<<];
build(,,n);
m=read();
while(m--){
scanf("%s",s+);int u=read()+,v=read()+;
switch(s[]){
case 'C':--u,--v,change(u,v);break;
case 'N':RRR(u,v);break;
case 'S':print(SUM(u,v));break;
default:{
print(s[]=='A'?MAX(u,v):MIN(u,v));
break;
}
}
}
Ot();
return ;
}
洛谷P1505 [国家集训队]旅游(树剖+线段树)的更多相关文章
- 洛谷 P1505 [国家集训队]旅游 树链剖分
目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 思路 AC代码 总结 题面 题目链接 P1505 [国家集训队]旅游 题目描述 Ray 乐 ...
- 洛谷 P1505 [国家集训队]旅游 解题报告
P1505 [国家集训队]旅游 题目描述 \(\tt{Ray}\) 乐忠于旅游,这次他来到了\(T\)城.\(T\)城是一个水上城市,一共有 \(N\) 个景点,有些景点之间会用一座桥连接.为了方便游 ...
- 洛谷P1505 [国家集训队]旅游
题目描述 \(Ray\) 乐忠于旅游,这次他来到了\(T\) 城.\(T\) 城是一个水上城市,一共有 \(N\) 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,\(T ...
- [洛谷]P1505 [国家集训队]旅游
题目链接: 传送门 题目分析: 树剖板,支持单点修改,区间取反,区间求最大值/最小值/和 区间取反取两次等于没取,维护一个\(rev\ tag\),每次打标记用\(xor\)打,记录是否需要翻转,\( ...
- 2018.06.29 洛谷P1505 [国家集训队]旅游(树链剖分)
旅游 题目描述 Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T 城的任意两个景点之间有且只有 ...
- 洛谷 P1975 [国家集训队]排队 Lebal:块内排序+树状数组
题目描述 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和. 红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别 ...
- 模板—点分治A(容斥)(洛谷P2634 [国家集训队]聪聪可可)
洛谷P2634 [国家集训队]聪聪可可 静态点分治 一开始还以为要把分治树建出来……• 树的结构不发生改变,点权边权都不变,那么我们利用刚刚的思路,有两种具体的分治方法.• A:朴素做法,直接找重心, ...
- 洛谷P4315 月下“毛景树”(树剖+线段树)
传送门 woc这该死的码农题…… 把每一条边转化为它连接的两点中深度较深的那一个,然后就可以用树剖+线段树对路径进行修改了 然后顺便注意在上面这种转化之后,树剖的时候不能搞$LCA$ 然后是几个注意点 ...
- BZOJ_2157_旅游_树剖+线段树
BZOJ_2157_旅游_树剖+线段树 Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但 ...
随机推荐
- python学习之-- 协程
协程(coroutine)也叫:微线程,是一种用户态的轻量级线程,就是在单线程下实现并发的效果.优点:1:无需线程上下文切换的开销.(就是函数之间来回切换)2:无需原子操作锁定及同步的开销.(如改一个 ...
- win8,win10里面内置的IE浏览器网银无法输入密码
win8,win10里面内置的IE浏览器网银无法输入密码,安装控件也没效果,部分网银直接导致IE崩溃,只需要简单设置即可解决. 方法/步骤 1 打开IE浏览器,点击右上角的小齿轮图标,在下拉菜单中 ...
- 如何使用sqlalchemy获取某年某月的数据总和
代码如下: # 基于Flask的SQLAlchemy # models class History(db.Model): __tablename__ = 'historys' id = db.Colu ...
- HTC 328T 如何恢复出厂设置
设置-存储-恢复出厂设置(在存储的最下面,往下拉)
- react 开发 PC 端项目(一)项目环境搭建 及 处理 IE8 兼容问题
步骤一:项目环境搭建 首先,你不应该使用 React v15 或更高版本.使用仍然支持 IE8 的 React v0.14 即可. 技术选型: 1.react@0.14 2.bootstrap3 3. ...
- 【Mongodb教程 第一课补加课2 】MongoDB下,启动服务时,出现“服务没有响应控制功能”解决方法
如图,如果通过下列代码,添加服务后,使用net start命令出现这样的问题时,可以参考下我的解决方法. D:\MongoDB>mongod --dbpath D:\MongoDB\Data - ...
- QtQuick桌面应用开发指导 1)关于教程 2)原型和设计 3)实现UI和功能_A
Release1.0 http://qt-project.org/wiki/developer-guides Qt Quick Application Developer Guide for Desk ...
- shell操作Hbase
status:查询集群的一些状态 hbase(main):002:0> status1 active master, 0 backup masters, 1 servers, 0 dead, 3 ...
- 2016/05/23 thinkphp M方法和D方法的区别
M方法和D方法的区别 ThinkPHP 中M方法和D方法都用于实例化一个模型类,M方法 用于高效实例化一个基础模型类,而 D方法 用于实例化一个用户定义模型类. 使用M方法 如果是如下情况,请考虑使用 ...
- Linux常用服务安装部署
1,centos7默认是装有python的,检查python版本的命令 # 检查python版本 : python -V 2,centOS在安装python3以及tab补全功能 下载python3源码 ...