【CC】Batman and Tree
Solution
一开始看到很懵。。感觉无从下手(因为自己太菜了qwq)
膜拜了题解之后发现好像并没有想象的那么复杂qwq
其实冷静下来考虑dp,用\(f[i]\)表示当前在\(i\)的最大能量值,然后对于一个从\(x\)到\(y\)的强盗,考虑找一条路径满足\(x\)到\(y\)的简单路径是其子路径,那么我们就可以用满足条件的路径的端点\(f\)值的最大值来更新走到的另一个端点处的新\(f\)值
将dfs序处理出来,不难发现满足条件的路径的端点对应的应该是几段区间,具体一点就是(默认\(dep[x]<=dep[y]\)):
(1)\(x\)是\(y\)的祖先,此时记\(dw\)为满足\(y\in subtree(dw)\)且\(dw\in son(x)\)的节点,那么可以选路径的的端点应该一个在区间\([1,st[dw]]\cup[ed[dw]+1,n]\)内,一个在\([st[y],ed[y]]\)内
(2)\(x\)不是\(y\)的祖先,那么此时可以选路径的端点应该一个在\([st[x],ed[x]]\),一个在\([st[y],ed[y]]\)内
那么直接线段树维护一下就好了,实现一个区间取max和区间查询max即可(吉老师线段树)
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int N=4e5+10,TOP=20;
const ll inf=1LL<<60;
struct xxx{
int y,nxt;
}a[N*2];
int h[N],lis[N],dep[N];
int st[N],ed[N],f[N][TOP+1];
int n,m,tot,dfn_t,dfn_t1;
int S,P,T;
namespace Seg{/*{{{*/
const int N=::N*4;
int ch[N][2];
ll tag[N],mx[N],smx[N],mn[N],smn[N];
int n,tot;
void pushup(int x){
if (mx[ch[x][0]]==mx[ch[x][1]]){
mx[x]=mx[ch[x][0]];
smx[x]=max(smx[ch[x][0]],smx[ch[x][1]]);
}
else{
int lw,up;
if (mx[ch[x][0]]>mx[ch[x][1]]) up=0,lw=1;
else up=1,lw=0;
mx[x]=mx[ch[x][up]];
smx[x]=max(smx[ch[x][up]],mx[ch[x][lw]]);
}
if (mn[ch[x][0]]==mn[ch[x][1]]){
mn[x]=mn[ch[x][0]];
smn[x]=min(smn[ch[x][0]],smn[ch[x][1]]);
}
else{
int lw,up;
if (mn[ch[x][0]]<mn[ch[x][1]]) lw=0,up=1;
else lw=1,up=0;
mn[x]=mn[ch[x][lw]];
smn[x]=min(smn[ch[x][lw]],mn[ch[x][up]]);
}
}
void _build(int x,int l,int r){
smx[x]=-inf; smn[x]=inf; tag[x]=0;
if (l==r){mx[x]=mn[x]=(::lis[l]==S?P:-inf);return;}
int mid=l+r>>1;
ch[x][0]=++tot; _build(ch[x][0],l,mid);
ch[x][1]=++tot; _build(ch[x][1],mid+1,r);
pushup(x);
}
void build(int _n){n=_n; tot=1; _build(1,1,n);}
void give_mxtag(int x,ll delta){
mn[x]=delta;
mx[x]=max(mx[x],delta);
tag[x]=max(tag[x],delta);
if (mn[x]==mx[x])
smn[x]=inf,smx[x]=-inf;
else
smx[x]=max(smx[x],delta);
}
void downtag(int x){
if (!tag[x]) return;
if (ch[x][0])
if (mn[ch[x][0]]<mn[x]&&mn[x]<smn[ch[x][0]])
give_mxtag(ch[x][0],tag[x]);
if (ch[x][1])
if (mn[ch[x][1]]<mn[x]&&mn[x]<smn[ch[x][1]])
give_mxtag(ch[x][1],tag[x]);
tag[x]=0;
}
void _update(int x,int l,int r,int lx,int rx,ll delta){
if (mn[x]>=delta) return;
if (l<=lx&&rx<=r&&delta<smn[x]){
give_mxtag(x,delta);
return;
}
downtag(x);
int mid=lx+rx>>1;
if (r<=mid) _update(ch[x][0],l,r,lx,mid,delta);
else if (l>mid) _update(ch[x][1],l,r,mid+1,rx,delta);
else{
_update(ch[x][0],l,mid,lx,mid,delta);
_update(ch[x][1],mid+1,r,mid+1,rx,delta);
}
pushup(x);
}
void update(int l,int r,ll delta){if (l<=r) _update(1,l,r,1,n,delta);}
ll _query(int x,int l,int r,int lx,int rx){
if (l<=lx&&rx<=r) return mx[x];
downtag(x);
int mid=lx+rx>>1;
if (r<=mid) return _query(ch[x][0],l,r,lx,mid);
else if (l>mid) return _query(ch[x][1],l,r,mid+1,rx);
else
return max(_query(ch[x][0],l,mid,lx,mid),_query(ch[x][1],mid+1,r,mid+1,rx));
}
ll query(int l,int r){return l>r?-inf:_query(1,l,r,1,n);}
void _debug(int x,int lx,int rx){
if (lx==rx){printf("%lld ",mx[x]); return;}
downtag(x);
int mid=lx+rx>>1;
_debug(ch[x][0],lx,mid);
_debug(ch[x][1],mid+1,rx);
}
void debug(){_debug(1,1,n);}
}/*}}}*/
void add(int x,int y){a[++tot].y=y; a[tot].nxt=h[x]; h[x]=tot;}
void dfs(int fa,int x,int d){
int u;
lis[++dfn_t]=x;
st[x]=dfn_t; dep[x]=d;
f[x][0]=fa;
for (int i=1;i<=TOP;++i) f[x][i]=f[f[x][i-1]][i-1];
for (int i=h[x];i!=-1;i=a[i].nxt){
u=a[i].y;
if (u==fa) continue;
dfs(x,u,d+1);
}
ed[x]=dfn_t;
}
int jump(int x,int d){
if (d==0) return x;
for (int i=0;i<=TOP;++i)
if (d>>i&1) x=f[x][i];
return x;
}
void debug(){
for (int i=1;i<=n;++i) printf("%lld ",Seg::query(i,i)); printf("\n");
}
void modify(int x,int y,int r,int t){
ll tmp1,tmp2;
int dw;
//dep[x]<dep[y]
if (dep[x]>dep[y]) swap(x,y);
if (st[x]<=st[y]&&st[y]<=ed[x]){
dw=jump(y,dep[y]-dep[x]-1);
tmp1=max(Seg::query(1,st[dw]-1),Seg::query(ed[dw]+1,n));
tmp2=Seg::query(st[y],ed[y]);
if (tmp2>r){
Seg::update(1,st[dw]-1,tmp2+t);
Seg::update(ed[dw]+1,n,tmp2+t);
}
if (tmp1>r)
Seg::update(st[y],ed[y],tmp1+t);
}
else{
tmp1=Seg::query(st[x],ed[x]);
tmp2=Seg::query(st[y],ed[y]);
if (tmp2>r)
Seg::update(st[x],ed[x],tmp2+t);
if (tmp1>r)
Seg::update(st[y],ed[y],tmp1+t);
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
int x,y,r,t;
scanf("%d",&T);
for (int o=1;o<=T;++o){
scanf("%d%d%d",&n,&S,&P);
memset(h,-1,sizeof(h));
tot=0;
for (int i=1;i<n;++i){
scanf("%d%d",&x,&y);
add(x,y); add(y,x);
}
dfn_t=0;
dfs(0,1,1);
Seg::build(n);
scanf("%d",&m);
for (int i=1;i<=m;++i){
scanf("%d%d%d%d",&x,&y,&r,&t);
modify(x,y,r,t);
}
printf("%lld\n",Seg::mx[1]);
}
}
【CC】Batman and Tree的更多相关文章
- 【数据结构】B-Tree, B+Tree, B*树介绍 转
[数据结构]B-Tree, B+Tree, B*树介绍 [摘要] 最近在看Mysql的存储引擎中索引的优化,神马是索引,支持啥索引.全是浮云,目前Mysql的MyISAM和InnoDB都支持B-Tre ...
- P3690 【模板】Link Cut Tree (动态树)
P3690 [模板]Link Cut Tree (动态树) 认父不认子的lct 注意:不 要 把 $fa[x]$和$nrt(x)$ 混 在 一 起 ! #include<cstdio> v ...
- LG3690 【模板】Link Cut Tree (动态树)
题意 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联通的 ...
- AC日记——【模板】Link Cut Tree 洛谷 P3690
[模板]Link Cut Tree 思路: LCT模板: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 30 ...
- LG3690 【模板】Link Cut Tree 和 SDOI2008 洞穴勘测
UPD:更新了写法. [模板]Link Cut Tree 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 后接两个整数(x,y),代表询问从x到y ...
- (RE) luogu P3690 【模板】Link Cut Tree
二次联通门 : luogu P3690 [模板]Link Cut Tree 莫名RE第8个点....如果有dalao帮忙查错的话万分感激 #include <cstdio> #includ ...
- LuoguP3690 【模板】Link Cut Tree (动态树) LCT模板
P3690 [模板]Link Cut Tree (动态树) 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两 ...
- 【LeetCode】199. Binary Tree Right Side View 解题报告(Python)
[LeetCode]199. Binary Tree Right Side View 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/probl ...
- 【数据结构】B-Tree, B+Tree, B*树介绍
[摘要] 最近在看Mysql的存储引擎中索引的优化,神马是索引,支持啥索引.全是浮云,目前Mysql的MyISAM和InnoDB都支持B-Tree索引,InnoDB还支持B+Tree索引,Memory ...
随机推荐
- 20155207王雪纯《网络对抗》Exp4 恶意代码分析
20155207 <网络对抗> 恶意代码分析 学习总结 实践目标 1.是监控你自己系统的运行状态,看有没有可疑的程序在运行. 2.是分析一个恶意软件,就分析Exp2或Exp3中生成后门软件 ...
- 20155211 网络攻防技术 Exp7 网络欺诈防范
20155211 网络攻防技术 Exp7 网络欺诈防范 实践内容 本实践的目标理解常用网络欺诈背后的原理,以提高防范意识,并提出具体防范方法.具体实践有 (1)简单应用SET工具建立冒名网站 (2)e ...
- 20155229《网络对抗技术》Exp3:免杀原理与实践
实验预习 免杀: 看为一种能使病毒木马避免被杀毒软件查杀的技术. 免杀的分类: 开源免杀:指在有病毒.木马源代码的前提下,通过修改源代码进行免杀.. 手工免杀:指在仅有病毒.木马的可执行文件(.exe ...
- 微信小程序 Echarts 异步数据更新
微信小程序 Echarts 异步数据更新的练习,被坑了很多次,特作记录. 作者:罗兵 地址:https://www.cnblogs.com/hhh5460/p/9989805.html 0.效果图 ...
- Invitation Cards POJ-1511 (spfa)
题目链接:Invitation Cards 题意: 给出一张有向图,现在要求从1到其他所有的结点的最小路径和与从所有其他结点到1的最小路径和之和. 题解: 求最小路径可以用SPFA来求解.从1到其他结 ...
- CS190.1x-ML_lab1_review_student
这是CS190.1x第一次作业,主要教你如何使用numpy.numpy可以说是python科学计算的基础包了,用途非常广泛.相关ipynb文件见我github. 这次作业主要分成5个部分,分别是:数学 ...
- ElasticSearch入门 第三篇:索引
这是ElasticSearch 2.4 版本系列的第三篇: ElasticSearch入门 第一篇:Windows下安装ElasticSearch ElasticSearch入门 第二篇:集群配置 E ...
- 代理神器allproxy
背景 allproxy意为all as proxy,即是说所有设备均可以成为一个网络代理,唯一的要求就是有网络访问权限. 一般的代理软件要求宿主机必须有公网地址,然后才能把网络代理出去,但在实际情况下 ...
- 《Deep Learning》(深度学习)中文版PDF免费下载
<Deep Learning>(深度学习)中文版PDF免费下载 "深度学习"经典著作<Deep Learning>中文版pdf免费下载. <Deep ...
- CocoaPods 遇到 A host target is a "parent" target which embeds a "child" target 问题解决
正在开发的项目中,集成RN,在使用cocoapods 时候,pod install 遇到如下问题: [!] Unable to find host target(s) for ****Extensio ...