Contest Hunter 模拟赛09 C [树形dp+差分]
题面
思路
又双叒叕是一道差分题我没想出来......记录一下
首先这个“所有祖先都比自己小”等价于“父亲比自己小”
这题的基础dp方程很显然,$dp[u][i]$表示当前在点$u$,且点$u$的值是$i$的时候最小修改几个点
然后我们发现每个$dp[u]$可以取到的有意义的值只有几个,所以我们考虑开一个$set$来维护这些取值和它们对应的$dp$值
这样并不方便转移:我们发现可以把$dp$值差分一下,每个$set$元素维护取值,以及这个取值的$dp$值和上一个取值的$dp$值之间的差——显然这个是单调递增的,否则会不优
然后发现我们可以启发式合并子树的$set$,然后针对当前点$dp$,返回的$dp$值需要保证所有儿子的$set$的最大值都大于这个$dp$值
然后就发现做完了,因为用了启发式合并,总复杂度为$O(n\log ^2 n)$
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cassert>
#include<set>
#define ll long long
using namespace std;
inline int read(){
int re=0,flag=1;char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') flag=-1;
ch=getchar();
}
while(isdigit(ch)) re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
return re*flag;
}
int n,first[200010],cnte=-1;
struct edge{
int to,next;
}a[400010];int w[200010];
bool fl[200010];
multiset<int>s[200010];
inline void add(int u,int v){
a[++cnte]=(edge){v,first[u]};first[u]=cnte;
a[++cnte]=(edge){u,first[v]};first[v]=cnte;
}
void dfs(int u,int f){
int i,v;fl[u]=1;
multiset<int>::iterator it;
for(i=first[u];~i;i=a[i].next){
v=a[i].to;if(v==f) continue;
dfs(v,u);fl[u]=fl[u]&&fl[v];
if(w[u]>w[v]) fl[u]=0;
if(s[u].size()<s[v].size()) s[u].swap(s[v]);
for(auto x:s[v]) s[u].insert(x);
s[v].clear();
}
// cout<<"finish dfs "<<u<<' '<<fl[u]<<'\n';
s[u].insert(1);
it=s[u].upper_bound(w[u]);it--;
s[u].erase(it);
s[u].insert(w[u]+1);
}
int main(){
memset(first,-1,sizeof(first));
n=read();int i,t1,t2;
for(i=1;i<=n;i++) w[i]=read();
for(i=1;i<n;i++){
t1=read();t2=read();
add(t1,t2);
}
dfs(1,0);
int minn=*s[1].begin(),ans=0;
if(fl[1]==1){puts("0");return 0;}
for(auto x:s[1]) if(x==minn) ans++; else break;
cout<<ans<<'\n';
}
Contest Hunter 模拟赛09 C [树形dp+差分]的更多相关文章
- Contest Hunter 模拟赛09 A [线段树维护斜率]
题面 传送门 思路 首先看看我们到底要干什么:有$1e6$次询问,遍历$i$,每次要求一个形如$b_i \ast a_j - a_i \ast b_j$的东西的最大值 考虑如果一个$j$的决策在当前的 ...
- CSP模拟赛 Repulsed(树形DP)
题面 ⼩ w ⼼⾥的⽕焰就要被熄灭了. 简便起⻅,假设⼩ w 的内⼼是⼀棵 n − 1 条边,n 个节点的树. 现在你要在每个节点⾥放⼀些个灭⽕器,每个节点可以放任意多个. 接下来每个节点都要被分配给 ...
- 4.9 省选模拟赛 圆圈游戏 树形dp set优化建图
由于圆不存在相交的关系 所以包容关系形成了树的形态 其实是一个森林 不过加一个0点 就变成了树. 考虑对于每个圆都求出最近的包容它的点 即他的父亲.然后树形dp即可.暴力建图n^2. const in ...
- 4.26 省选模拟赛 T3 状压dp 差分求答案
LINK:T3 比较好的题目 考试的时候被毒瘤的T2给搞的心态爆炸 这道题连正解的思路都没有想到. 一看到题求删除点的最少个 可以使得不连通. 瞬间想到最小割 发现对于10分直接跑最小割即可. 不过想 ...
- 模拟赛毒瘤状压DP题:Kronican
Kronican 内存限制:32 MiB 时间限制:2000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 上传者: cqbzgm 题目描述 Mislav有N个无限体积的杯子,每一个杯子中都 ...
- 2019.6.1 模拟赛——[ 费用流 ][ 数位DP ][ 计算几何 ]
第一题:http://codeforces.com/contest/1061/problem/E 把点集分成不相交的,然后跑费用流即可.然而错了一个点. #include<cstdio> ...
- 2018.10.30 NOIP模拟 排列树(树形dp+组合数学)
传送门 考试的时候乱搞过了. 其实题目就是让你求拓扑排序方案数. 直接树形dpdpdp然后组合数转移一下就行了. 乱搞代码
- 2018.10.04 NOIP模拟 航班(tarjan+树形dp)
传送门 考场上自己yy了一个双连通只有40分. 然后换根dp求最长路就行了. 代码
- 【NOIP模拟赛】超级树 DP
这个题我在考试的时候把所有的转移都想全了就是新加一个点时有I.不作为II.自己呆着III.连一个IV.连接两个子树中的两个V连接一个子树中的两个,然而V我并不会转移........ 这个题的正解体现了 ...
随机推荐
- web3.js_1.x.x--API(二)/合约部署与事件调用
web3.js_1.x.x的使用和网上查到的官方文档有些不同,我对经常使用到的API进行一些整理,希望能帮到大家 转载博客:http://www.cnblogs.com/baizx/p/7474774 ...
- js判断是否为数字
function isNumber(value) { var patrn = /^(-)?\d+(\.\d+)?$/; if (patrn.exec(value) == null || value = ...
- Ubunut18.04与Windows传输文件的方式
ubunut18.04与Windows传输文件的方式 开发环境:ubuntu18.04; 虚拟机:virtual box; 操作系统:Win10_64bits/专业版 在以前使用的ubuntu12.0 ...
- python3爬虫之开篇
写在前面的话: 折腾爬虫也有一段时间了,从一开始的懵懵懂懂,到现在的有一定基础,对于这一路的跌跌撞撞,个人觉得应该留下一些文字性的东西,毕竟好记性不如烂笔头,而且毕竟这是吃饭的家伙,必须用心对待才可以 ...
- 嵌入式linux系统移植(一)
内容: 交叉编译环境 bootloader功能子系统 内核核心子系统 文件系统子系统要点: 搭建交叉编译环境 bootloader的选择和移植 kernel的配置.编译.移植和调 ...
- 【ajax】ajax异步实现用户注册验证
从前台到后台实现简单用户注册检查用户是否存在 1.编写domain public class User { private String username; private String passwo ...
- 2.PostgreSQL安装详细步骤(windows)【转】
感谢 Junn9527 PostgreSQL安装:一.windows下安装过程安装介质:postgresql-9.1.3-1-windows.exe(46M),安装过程非常简单,过程如下:1.开始安装 ...
- T分布、卡方分布、F分布
请参考: https://www.cnblogs.com/think-and-do/p/6509239.html
- spring boot 入门3 如何在springboot 上使用AOP
Aop是spring的两大核心之一 那么如何在springboot中采用注解的形式实现aop那? 1)首先我们定义一个相关功能的切面类 并 采用@Aspect 注解来声明当前类为切面 同时采用@Com ...
- React+DvaJS 之 hook 路由权限控制
博客 学院 下载 GitChat TinyMind 论坛 APP 问答 商城 VIP 活动 招聘 ITeye 写博客 发Chat 登录注册 原 React+DvaJS 之 hook 路由权限控制 20 ...