LUOGU P1505 [国家集训队]旅游 (树链剖分+线段树)
解题思路
快被调死的码农题,,,其实就是一个边权下放到点权的线段树+树剖。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib> using namespace std;
const int MAXN = ;
const int inf = 0x3f3f3f3f; inline int rd(){
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {f=ch=='-'?:;ch=getchar();}
while(isdigit(ch)) {x=(x<<)+(x<<)+ch-'';ch=getchar();}
return f?x:-x;
} int n,m,head[MAXN],cnt=,to[MAXN<<],nxt[MAXN<<],val[MAXN<<],num;
int w[MAXN],wt[MAXN],id[MAXN],top[MAXN],siz[MAXN],son[MAXN],fa[MAXN],dep[MAXN];
int Sum[MAXN<<],Min[MAXN<<],Max[MAXN<<];
bool rev[MAXN<<],lazy[MAXN<<]; inline void add(int bg,int ed,int ww){
to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt,val[cnt]=ww;
} void dfs1(int x,int f,int d){
dep[x]=d,fa[x]=f,siz[x]=;int maxson=-,u;
for(register int i=head[x];i;i=nxt[i]){
u=to[i];if(u==f) continue;
dfs1(u,x,d+);siz[x]+=siz[u];w[u]=val[i];
if(siz[u]>maxson) {maxson=siz[u];son[x]=u;}
}
} void dfs2(int x,int topf){
top[x]=topf;id[x]=++num;wt[num]=w[x];
if(!son[x]) return;dfs2(son[x],topf);int u;
for(register int i=head[x];i;i=nxt[i]){
u=to[i];if(u==fa[x] || u==son[x]) continue;
dfs2(u,u);
}
} inline void pushdown(int x){
rev[x<<]^=;rev[x<<|]^=;rev[x]^=;
Sum[x<<]=-Sum[x<<];Sum[x<<|]=-Sum[x<<|];
swap(Min[x<<],Max[x<<]);swap(Min[x<<|],Max[x<<|]);
Min[x<<]=-Min[x<<];Min[x<<|]=-Min[x<<|];
Max[x<<]=-Max[x<<];Max[x<<|]=-Max[x<<|];
} void build(int x,int l,int r){
if(l==r) {if(l==) Min[x]=inf,Max[x]=-inf; else Sum[x]=Min[x]=Max[x]=wt[l];return;}
int mid=(l+r)>>;
build(x<<,l,mid);build(x<<|,mid+,r);
Sum[x]=Sum[x<<]+Sum[x<<|];
Min[x]=min(Min[x<<],Min[x<<|]);
Max[x]=max(Max[x<<],Max[x<<|]);
} void update(int x,int l,int r,int L,int R,int ww){
if(L<=l && r<=R) {
if(ww==-inf) {rev[x]^=;Sum[x]=-Sum[x];swap(Min[x],Max[x]);Min[x]=-Min[x];Max[x]=-Max[x];}
else Sum[x]=Min[x]=Max[x]=ww;
return;
}
int mid=(l+r)>>;if(rev[x]) pushdown(x);
if(L<=mid) update(x<<,l,mid,L,R,ww);
if(mid<R) update(x<<|,mid+,r,L,R,ww);
Sum[x]=Sum[x<<]+Sum[x<<|];
Min[x]=min(Min[x<<],Min[x<<|]);
Max[x]=max(Max[x<<],Max[x<<|]);
} int query_Sum(int x,int l,int r,int L,int R){
if(L<=l && r<=R) return Sum[x];
int mid=(l+r)>>,ret=;if(rev[x]) pushdown(x);
if(L<=mid) ret+=query_Sum(x<<,l,mid,L,R);
if(mid<R) ret+=query_Sum(x<<|,mid+,r,L,R);
return ret;
} int query_Max(int x,int l,int r,int L,int R){
if(L<=l && r<=R) return Max[x];
int mid=(l+r)>>,ret=-inf;if(rev[x]) pushdown(x);
if(L<=mid) ret=max(ret,query_Max(x<<,l,mid,L,R));
if(mid<R) ret=max(ret,query_Max(x<<|,mid+,r,L,R));
return ret;
} int query_Min(int x,int l,int r,int L,int R){
if(L<=l && r<=R) return Min[x];
int mid=(l+r)>>,ret=inf;if(rev[x]) pushdown(x);
if(L<=mid) ret=min(ret,query_Min(x<<,l,mid,L,R));
if(mid<R) ret=min(ret,query_Min(x<<|,mid+,r,L,R));
return ret;
} void updRev(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
update(,,n,id[top[x]],id[x],-inf);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
if(x!=y) update(,,n,id[x]+,id[y],-inf);
} inline int qSum(int x,int y){
int ret=;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ret+=query_Sum(,,n,id[top[x]],id[x]);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
if(x!=y) ret+=query_Sum(,,n,id[x]+,id[y]);
return ret;
} inline int qMax(int x,int y){
int ret=-inf;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ret=max(ret,query_Max(,,n,id[top[x]],id[x]));
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
if(x!=y) ret=max(ret,query_Max(,,n,id[x]+,id[y]));
return ret;
} inline int qMin(int x,int y){
int ret=inf;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ret=min(ret,query_Min(,,n,id[top[x]],id[x]));
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);if(x!=y) ret=min(ret,query_Min(,,n,id[x]+,id[y]));
return ret;
} inline int pre(int x){
return dep[to[x<<]]>dep[to[x<<^]]?to[x<<]:to[x<<^];
} int main(){
// freopen("wrong.out","w",stdout);
n=rd();int x,y,z;char s[];
for(int i=;i<n;i++){
x=rd()+,y=rd()+,z=rd();
add(x,y,z),add(y,x,z);
}
dfs1(,,);dfs2(,);build(,,n);m=rd();
while(m--){
scanf("%s",s+);x=rd(),y=rd();
if(s[]=='C') update(,,n,id[pre(x)],id[pre(x)],y);
else if(s[]=='N') updRev(x+,y+);
else if(s[]=='S') printf("%d\n",qSum(x+,y+));
else if(s[]=='A') printf("%d\n",qMax(x+,y+));
else printf("%d\n",qMin(x+,y+));
}
return ;
}
LUOGU P1505 [国家集训队]旅游 (树链剖分+线段树)的更多相关文章
- BZOJ2157旅游——树链剖分+线段树
题目描述 Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T 城的任意两个景点之间有且只有一条路 ...
- bzoj 2157: 旅游【树链剖分+线段树】
裸的树链剖分+线段树 但是要注意一个地方--我WA了好几次才发现取完相反数之后max值和min值是要交换的-- #include<iostream> #include<cstdio& ...
- 洛谷P3313 [SDOI2014]旅行 题解 树链剖分+线段树动态开点
题目链接:https://www.luogu.org/problem/P3313 这道题目就是树链剖分+线段树动态开点. 然后做这道题目之前我们先来看一道不考虑树链剖分之后完全相同的线段树动态开点的题 ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
- HDU4897 (树链剖分+线段树)
Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...
- Aizu 2450 Do use segment tree 树链剖分+线段树
Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...
随机推荐
- Unity 之旋转
代码如下: bool RotateDelta(Vector3 direction) { direction.y = ; if (direction == Vector3.zero) return tr ...
- MongoDB点滴
0 http://blog.csdn.net/mydeman/article/details/6652387 1 MongoDB 内置连接池,不需要使用额外的连接池驱动 Note: The Mongo ...
- MySQL数据库中,将一个字段的值分割成多条数据显示
本文主要记录如何在MySQL数据库中,将一个字符串分割成多条数据显示. 外键有时是以字符串的形式存储,例如 12,13,14 这种,如果以这种形式存储,则不能直接与其他表关联查询,此时就需要将该字段的 ...
- 你没玩过的全新版本!Win10这些骚操作你知多少
你没玩过的全新版本!Win10这些骚操作你知多少 [PConline技巧]不知不觉,Win10与我们相伴已经整整四个年头了,从最开始的组团抗拒到现在的默默接受,个中滋味相信谁心里都有个数.近日微软开始 ...
- 全面解析HTML5优缺点
HTML5是当下最主流的网页标准,它的出现给在线应用和手机游戏开发者带来了不少新机会.基于HTML5,开发者可以制作自己的网络游戏,而这个游戏无 论你在PC.手机还是平板电脑上,无论你用Chrome. ...
- UVA 12304 /// 圆的综合题 圆的模板
题目大意: ①给出三角形三个点,求三角形外接圆,求外接圆的圆心和半径. ②给出三角形三个点,求三角形内接圆,求内接圆的圆心和半径. ③给出一个圆,和一个点,求过该点的圆的切线与x轴的夹角(0<= ...
- openwrt_ipsec_function.sh 分析
#!/bin/sh # # Copyright (C) Vitaly Protsko <villy@sft.ru> errno= # get_fieldval gate src " ...
- mkdir: Cannot create directory /file. Name node is in safe mode.
刚刚在hadoop想创建一个目录的时候,发现报错了 具体信息如下: [hadoop@mini1 hadoop-2.6.4]$ hadoop fs -mkdir /file mkdir: Cannot ...
- CSS——垂直居中
vertical-align 垂直对齐 以前我们讲过让带有宽度的块级元素居中对齐,是margin: 0 auto; 以前我们还讲过让文字居中对齐,是 text-align: center; 但是我们从 ...
- dos中文乱码怎么办?
最简单的方法: 通过 chcp命令改变代码页,UTF-8的代码页为65001 即chcp 65001 chcp 65001 就是换成UTF-8代码页 chcp 936 可以换回默认的GBK chcp ...