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的难度为 ...
随机推荐
- <七>理解多态
理解多态 多种多样的形态(静态多态,动态多态) 静态多态(编译时期) 1:函数重载 bool comparet(int ,int); bool compare(double,double); comp ...
- EASE-Grid经纬度与行列号转换公式 以 25KM的HDF数据为例
/// <summary> /// 把经纬度转换成行列号 /// </summary> /// <param name="pLng"></ ...
- 通过 CancellationToken 提高 Web 性能
在 Web 开发中,经常会遇到这样的场景:用户发起一个请求,Web 服务器执行一些计算密集型的操作,等待结果返回给用户.这种情况下,如果用户在等待结果的过程中取消了请求,那么服务器端依然会继续执行计算 ...
- texlive安装与vscode环境配置
环境 系统:windows10 texlive下载 下载地址: 官网:http://tug.org/texlive/ 清华镜像源: https://mirrors.tuna.tsinghua.edu. ...
- 基于 Traefik 如何实现 path 末尾自动加斜杠?
前言 Traefik 是一个现代的 HTTP 反向代理和负载均衡器,使部署微服务变得容易. Traefik 可以与现有的多种基础设施组件(Docker.Swarm 模式.Kubernetes.Mara ...
- 3D视觉算法初学概述
背景知识 RGB-D相机 一,基于3DMM的三维人脸重建技术概述 1.1,3D 人脸重建概述 1.2,初版 3DMM 二,视觉SLAM算法基础概述 2.1,视觉里程计 2.2,后端优化 2.3,回环检 ...
- [数据与分析可视化] D3入门教程1-d3基础知识
d3.js入门教程1-d3基础知识 文章目录 d3.js入门教程1-d3基础知识 1 HTML介绍 1.1 什么是HTML? 1.2 自定义文档样式CSS 1.3 构建svg图形 2 d3绘图入门 2 ...
- [Untiy]贪吃蛇大作战(一)——开始界面
前言: 刚学unity没多久吧(大概1个月多点),这是我自己做的除官网之外的第一个游戏demo,中间存在很多不足的地方,但是还是希望可以给需要的人提供一些思路和帮助,有问题的小伙伴可以找我一起探讨一起 ...
- MySQL 索引的创建、删除
MySQL中索引的创建有三种方法,索引的删除有两种方法. 一.创建索引 (1)使用create index # 1.创建普通索引 create index 索引名 on 表名 (列名[(限制索引长度) ...
- 轻松理解Promise.all 、Promise.then、Promise.race有什么区别以及使用方法
简单来说呢,Promse.all一般应用于某个场景需要多个接口数据合并起来才能实现 有个极大地好处我必须说一下,请求顺序和获取数据顺序是一样的哟,大可放心使用~~ const success1 = n ...