【Luogu】P3313旅行(树链剖分)
动态开点的树链剖分qwq。
跟小奇的花园一模一样,不做过多讲解。
#include<cstdio>
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<algorithm>
#define maxn 100010
#define mid ((l+r)>>1)
#define check(x) if(x==0) x=++tot;
using namespace std;
inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} struct Edge{
int next,to;
}edge[maxn*];
int head[maxn],num;
inline void add(int from,int to){
edge[++num]=(Edge){head[from],to};
head[from]=num;
} int dfn[maxn];
int back[maxn],cnt;
int sum[maxn*],tot;
int mav[maxn*];
int root[maxn];
int ls[maxn*];
int rs[maxn*];
int top[maxn];
int size[maxn];
int son[maxn];
int deep[maxn];
int father[maxn];
int d[maxn];
int q[maxn];
int n,m; void find(int x,int fa){
size[x]=;deep[x]=deep[fa]+;
for(int i=head[x];i;i=edge[i].next){
int to=edge[i].to;
if(to==fa) continue;
father[to]=x;
find(to,x);
size[x]+=size[to];
if(son[x]==||size[son[x]]<size[to]) son[x]=to;
}
} void unionn(int x,int Top){
dfn[x]=++cnt; back[cnt]=x;
top[x]=Top;
if(son[x]==) return;
unionn(son[x],Top);
for(int i=head[x];i;i=edge[i].next){
int to=edge[i].to;
if(to==father[x]||to==son[x]) continue;
unionn(to,to);
}
} inline void pushup(int rt){
sum[rt]=sum[ls[rt]]+sum[rs[rt]];
mav[rt]=max(mav[ls[rt]],mav[rs[rt]]);
} void update(int o,int num,int l,int r,int &rt){
check(rt);
if(l==r){
sum[rt]=num;
mav[rt]=num;
return;
}
if(o<=mid) update(o,num,l,mid,ls[rt]);
else update(o,num,mid+,r,rs[rt]);
pushup(rt);
return;
} int quemax(int from,int to,int l,int r,int &rt){
if(rt==) return ;
if(from<=l&&to>=r) return mav[rt];
int ans=;
if(from<=mid) ans=max(ans,quemax(from,to,l,mid,ls[rt]));
if(to>mid) ans=max(ans,quemax(from,to,mid+,r,rs[rt]));
return ans;
} int quesum(int from,int to,int l,int r,int &rt){
if(rt==) return ;
if(from<=l&&to>=r) return sum[rt];
int ans=;
if(from<=mid) ans+=quesum(from,to,l,mid,ls[rt]);
if(to>mid) ans+=quesum(from,to,mid+,r,rs[rt]);
return ans;
} int askmax(int from,int to,int val){
int ans=;
while(top[from]!=top[to]){
if(deep[top[from]]<deep[top[to]]) swap(from,to);
ans=max(ans,quemax(dfn[top[from]],dfn[from],,n,root[val]));
from=father[top[from]];
}
if(deep[from]>=deep[to]) swap(from,to);
ans=max(ans,quemax(dfn[from],dfn[to],,n,root[val]));
return ans;
} int asksum(int from,int to,int val){
int ans=;
while(top[from]!=top[to]){
if(deep[top[from]]<deep[top[to]]) swap(from,to);
ans+=quesum(dfn[top[from]],dfn[from],,n,root[val]);
from=father[top[from]];
}
if(deep[from]>=deep[to]) swap(from,to);
ans+=quesum(dfn[from],dfn[to],,n,root[val]);
return ans;
} void chancol(int pos,int val){
update(dfn[pos],,,n,root[q[pos]]);
update(dfn[pos],d[pos],,n,root[val]);
q[pos]=val;
} void channum(int pos,int val){
update(dfn[pos],val,,n,root[q[pos]]);
d[pos]=val;
} int main(){
n=read(),m=read();
for(int i=;i<=n;++i){
d[i]=read();q[i]=read();
}
for(int i=;i<n;++i){
int x=read(),y=read();
add(x,y);
add(y,x);
}
find(,);
unionn(,);
for(int i=;i<=n;++i) update(dfn[i],d[i],,n,root[q[i]]);
for(int i=;i<=m;++i){
char c[];
scanf("%s",c);
if(c[]=='C'){
if(c[]=='C'){
int x=read(),y=read();
chancol(x,y);
}
else{
int x=read(),y=read();
channum(x,y);
}
}
else if(c[]=='Q'){
if(c[]=='S'){
int x=read(),y=read();
printf("%d\n",asksum(x,y,q[x]));
}
else{
int x=read(),y=read();
printf("%d\n",askmax(x,y,q[x]));
}
}
}
return ;
}
https://www.luogu.org/problemnew/show/P3313
【Luogu】P3313旅行(树链剖分)的更多相关文章
- [luogu P3384] [模板]树链剖分
[luogu P3384] [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点 ...
- P3313 [SDOI2014]旅行——树链剖分+线段树(动态开点?)
P3313 [SDOI2014]旅行 一棵树,其中的点分类,点有权值,在一条链上找到一类点中的最大值或总和: 树链剖分把树变成链: 把每个宗教单开一个线段树,维护区间总和和最大值: 宗教很多,需要动态 ...
- 洛谷P3313 [SDOI2014]旅行(树链剖分 动态开节点线段树)
题意 题目链接 Sol 树链剖分板子 + 动态开节点线段树板子 #include<bits/stdc++.h> #define Pair pair<int, int> #def ...
- BZOJ 3531: [Sdoi2014]旅行 [树链剖分]
3531: [Sdoi2014]旅行 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1685 Solved: 751[Submit][Status] ...
- BZOJ3531:[SDOI2014]旅行(树链剖分)
Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足 从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰 ...
- BZOJ 3531 [Sdoi2014]旅行 树链剖分+动态开点线段树
题意 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. 为了方便,我们用 ...
- cogs 186. [USACO Oct08] 牧场旅行 树链剖分 LCA
186. [USACO Oct08] 牧场旅行 ★★☆ 输入文件:pwalk.in 输出文件:pwalk.out 逐字节对比时间限制:1 s 内存限制:128 MB n个被自然地编号为 ...
- BZOJ 2157 旅行(树链剖分码农题)
写了5KB,1发AC... 题意:给出一颗树,支持5种操作. 1.修改某条边的权值.2.将u到v的经过的边的权值取负.3.求u到v的经过的边的权值总和.4.求u到v的经过的边的权值最大值.5.求u到v ...
- [BZOj4336][BJOI2015]骑士的旅行(树链剖分+线段树)
树链剖分,对每个叶子用multiset记录前K大士兵,其余节点通过从儿子归并维护前K大士兵.过于模板. #include<set> #include<cstdio> #incl ...
- BZOJ 3531 SDOI2014 旅行 树链剖分+线段树动态开点
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3531 题意概述: 给出一棵N个点的树,树上的每个结点有一个颜色和权值,支持以下四种操作: ...
随机推荐
- 洛谷 P1074 靶形数独
题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他 们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教, Z 博士拿出了他最近发明的 ...
- .net 实现的上传下载,如果是图片就显示上传的图片
HTML: <div> <input id="fileUpload" type="file" runat="server" ...
- UVA225 Golygons 黄金图形(dfs+回溯)
剪枝1:在同一个维度上的点具有相同的奇偶性,如果奇数数量只有奇数个那么一定不能返回原点. 剪枝2:当前位置怎么也走不回去. 3:沿途判断障碍即可. 在oj上提交0.347s,最快的0.012s,应该有 ...
- [torch] torch.contiguous
torch.contiguous 作用 连续存储,因为view的操作要求的是连续的内容. 详细 考虑下面的操作,transpose操作只是改变了stride,而实际数组存储的内容并没有得到任何改变,即 ...
- [论文理解] Connectionist Text Proposal Network
Connectionist Text Proposal Network 简介 CTPN是通过VGG16后在特征图上采用3*3窗口进行滑窗,采用与RPN类似的anchor机制,固定width而只预测an ...
- 2018.3.16 win 关闭自动更新代码
新建一个文本文件修改后缀名为 .bat 格式 net stop wuauserv sc config wuauserv start=disabled shutdown -r -t 1
- python之可迭代对象
1. 可迭代对象是什么? 字面意思分析:可以重复的迭代的实实在在的东西 专业角度: 内部含有'__iter__'方法的对象,就是可迭代对象 2. 可迭代对象都有什么? list,dict(keys() ...
- vector 下标操作
比如:vector<int> ivec(3).. 当采用下标操作ivec[10]的时候,该操作是未定义的,在自己的机器上输出的值是零.建议使用迭代器进行操作.
- vue 点击下拉框
data: { hide:false, zhi:"全部" }, <div class="item"> <div class="c2c ...
- Latex使用笔记,中文,字号等
中文 编译器选择的xelatex 或者lualatex 我试过的两种方式(都是基于ctex的). 直接使用ctex的基本documentclass \documentclass[UTF8]{ctexa ...