CF796C Bank Hacking
思路
放眼整个题解区没有我这种解法,因此来写一篇题解。
既然要求我们选择一个节点作为根,那么我们就枚举根。
接下来的问题就是如何 \(\mathcal{O}(1)\) 或 \(\mathcal O(\log n)\) 计算贡献。
我们可以把节点分为四类:这个节点,这个节点的父亲,这个节点的儿子,另外的节点。
其中第 \(1/2\) 类非常容易解决。难解决的就是这个节点的儿子和另外的节点。
不妨考虑线段树,把这个节点所有的儿子压到一个区间内,为此,我们需要寻找一种新的编号方式。
原本正常把树拍扁都是根据 \(\mathcal DFS\) 序遍历的,现在我们需要以 \(\mathcal BFS\) 序遍历,而且以点 \(i\) 为根时,它原本的父亲 \(fa_i\) 也会变成它的儿子。
于是如此模拟即可。
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
int const N=1e6+10;
int n,go[N];
struct node{int w,id;}a[N];
int vis[N],fa[N],minx[N],maxx[N],c[N];
vector<int>b[N];
struct Segment_Tree{
#define ls (x<<1)
#define rs (x<<1|1)
#define mid ((l+r)>>1)
int c[N<<2];
inline void build(int x,int l,int r){
if (l==r){c[x]=a[l].w;return;}
build(ls,l,mid);build(rs,mid+1,r);
c[x]=max(c[ls],c[rs]);
}
inline void update(int x,int l,int r,int p,int v){
if (l==r){c[x]=v;return;}
if (p<=mid) update(ls,l,mid,p,v);
else update(rs,mid+1,r,p,v);
c[x]=max(c[ls],c[rs]);
}
inline int query(int x,int l,int r,int ll,int rr){
if (ll<=l && r<=rr) return c[x];
int res=-2e9;
if (ll<=mid) res=max(res,query(ls,l,mid,ll,rr));
if (mid<rr) res=max(res,query(rs,mid+1,r,ll,rr));
return res;
}
}T;
inline bool cmp(node x,node y){return x.id<y.id;}
inline int solve(int x){
int la=0;
if (fa[x]) la=c[fa[x]],T.update(1,1,n,go[fa[x]],-2e9);
T.update(1,1,n,go[x],-2e9);
int res=c[x];
if (minx[x]<=maxx[x]) res=max(res,T.query(1,1,n,minx[x],maxx[x])+1);
if (minx[x]-1>=1) res=max(res,T.query(1,1,n,1,minx[x]-1)+2);
if (maxx[x]+1<=n) res=max(res,T.query(1,1,n,maxx[x]+1,n)+2);
if (fa[x]) res=max(res,la+1),T.update(1,1,n,go[fa[x]],la);
T.update(1,1,n,go[x],c[x]);
return res;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n;
for (int i=1;i<=n;++i) cin>>a[i].w,c[i]=a[i].w;
queue<int>q;
for (int i=1;i<n;++i){
int u,v;cin>>u>>v;
b[u].push_back(v);
b[v].push_back(u);
}
q.push(1);vis[1]=1;a[1].id=1;
int cnt=1;
while (!q.empty()){
int x=q.front();q.pop();
minx[x]=cnt+1;vis[x]=1;
for (auto v:b[x]){
if (vis[v]) continue;
fa[v]=x;
a[v].id=++cnt;q.push(v);
}
maxx[x]=cnt;
}
for (int i=1;i<=n;++i) go[i]=a[i].id;
sort(a+1,a+n+1,cmp);
T.build(1,1,n);
int ans=9e18;
for (int i=1;i<=n;++i) ans=min(ans,solve(i));
cout<<ans<<'\n';
return 0;
}
CF796C Bank Hacking的更多相关文章
- CF796C Bank Hacking 思维
Although Inzane successfully found his beloved bone, Zane, his owner, has yet to return. To search f ...
- CF796C Bank Hacking 题解
洛谷链接 题目 Although Inzane successfully found his beloved bone, Zane, his owner, has yet to return. To ...
- CF796C Bank Hacking 细节
思路十分简单,答案只有 3 种可能,但是有一些细节需要额外注意一下. code: #include <bits/stdc++.h> #define N 300002 #define set ...
- C. Bank Hacking 解析(思維)
Codeforce 796 C. Bank Hacking 解析(思維) 今天我們來看看CF796C 題目連結 題目 略,請直接看原題. 前言 @copyright petjelinux 版權所有 觀 ...
- Code Forces 796C Bank Hacking(贪心)
Code Forces 796C Bank Hacking 题目大意 给一棵树,有\(n\)个点,\(n-1\)条边,现在让你决策出一个点作为起点,去掉这个点,然后这个点连接的所有点权值+=1,然后再 ...
- codeforce 796C - Bank Hacking(无根树+思维)
题目 Although Inzane successfully found his beloved bone, Zane, his owner, has yet to return. To searc ...
- CodeForces - 796C Bank Hacking
思路:共有n-1条边连接n个点,即形成一棵树.一开始需要选择一个点hack--将这个点视为根结点,与它相邻的点防御值加1,与它相隔一个在线点的点的防御也加1.当根节点被hack,即这个点被删除,又变成 ...
- Codeforces Round #408 (Div. 2) C. Bank Hacking
http://codeforces.com/contest/796/problem/C Although Inzane successfully found his beloved bone, Zan ...
- Codeforces Round #408 (Div. 2)C. Bank Hacking(STL)
题目链接:http://codeforces.com/problemset/problem/796/C 题目大意:有n家银行,第一次可以攻击任意一家银行(能量低于自身),跟被攻击银行相邻或者间接相邻( ...
- Codeforces Round #408 (Div. 2) C.Bank Hacking(二分)
传送门 题意 给出n个银行,银行之间总共有n-1条边,定义i与j有边相连为neighboring,i到j,j到k有边,则定义i到k的关系为semi- neighboring, 每家银行hack的难度为 ...
随机推荐
- 第2-4-9章 规则引擎Drools实战(2)-信用卡申请
目录 9.2 信用卡申请 9.2.1 计算规则 9.2.2 实现步骤 9.2 信用卡申请 全套代码及资料全部完整提供,点此处下载 本小节我们需要通过Drools规则引擎来根据规则进行申请人的合法性检查 ...
- webflux延迟队列逻辑更改过程记录
title : webflux延迟队列逻辑更改过程记录 author : simonLee date : 2022/11/22 10:26 目录 webflux延迟队列逻辑更改过程记录 一.问题背景 ...
- 大数据-业务数据采集-FlinkCDC
CDC CDC 是 Change Data Capture(变更数据获取)的简称.核心思想是,监测并捕获数据库的变动(包括数据或数据表的插入.更新以及删除等),将这些变更按发生的顺序完整记录下来,写入 ...
- 动态SQL遇到的问题
看图 查不出来任何数据 因为判断有问题 修改方法如下:
- for循环结构、range方法
目录 今日内容总结 whlie补充说明 for循环结构 range方法 练习 今日内容总结 whlie补充说明 1.死循环 真正死循环是一旦执行 CPU功耗会急速上升 直到系统采取紧急措施 尽量不要让 ...
- Anaconda下载安装
下载地址: 链接:https://pan.baidu.com/s/1fmJkMSL6amJF4KP5JwklOQ 提取码:dsyc 安装完成之后,记得配置系统环境变量:
- linux系统中安装虚拟机
在linux系统中,利用图形化界面安装虚拟机.首先启动 virt-manager,当然没有安装 virt-manager需要先安装好. 1 $ apt-get install virt-manager ...
- 2021强网杯青少赛(qwtac)楼上大佬ddw WriteUp
楼上大佬ddw战队WRITEUP 战队信息 战队名称:楼上大佬ddw 战队排名:24 解题情况 解题过程 01 签到 操作内容: 下载附件,打开运行拿到flag 如该题使用自己编写的脚本代码请详细写出 ...
- BBS项目(二): 登录功能 首页导航条搭建 首页主体部分 个人站点页面搭建 文章分类与标签 日期归档
目录 登录功能 pillow模块生成验证码 前端发送ajax请求 后端auth模块校验 sweetalert弹窗提示登录失败 首页导航条搭建 修改密码 退出登录 首页主体部分 首页前端框架搭建 adm ...
- [cocos2d-x]飞机大战 遇到的bug和总结(一)
第一点: Sequence* sequence=Sequence::create(actionMove, actionFinished,NULL); create方法的最后必须加上NULL,不然会报出 ...