题解

这道题很显然可以想出来一个\(n^2\)的dp,也就是dp[u][i]表示以u为根的子树最大值是i的点集最大是多少(i是离散化后的值)

就是对于每个儿子处理出后缀最大值然后按位相加更新父亲,我们把最大值处理成差分来存储,儿子们的最大值按位相加等于差分按位相加,后缀最大值出现了变化仅当加入了父亲节点形成一个点集,也就是父亲节点的值w[u],所在的位置,跳过差分一串连续的0,遇到第一个有数的值,然后减掉,可以用map

代码

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <queue>
//#define ivorysi
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define mo 974711
#define MAXN 200005
#define eps 1e-3
#define RG register
#define calc(x) __builtin_popcount(x)
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {putchar('-');x = -x;}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
struct node {
int to,next;
}E[MAXN * 2];
int head[MAXN],sumE,N,w[MAXN],a[MAXN],tot;
map<int,int> dp[MAXN];
void add(int u,int v) {
E[++sumE].to = v;E[sumE].next = head[u];head[u] = sumE;
}
void merge(int u,int v) {
if(dp[u].size() < dp[v].size()) swap(dp[u],dp[v]);
for(auto k : dp[v]) dp[u][k.fi] += k.se;
dp[v].clear();
}
void dfs(int u,int fa) {
for(int i = head[u] ; i ;i = E[i].next) {
int v = E[i].to;
if(v != fa) {
dfs(v,u);
merge(u,v);
}
}
map<int,int>::iterator k = dp[u].begin();
if(k->fi >= w[u]) return;
k = dp[u].lower_bound(w[u]);--k;
if(k->se == 1) dp[u].erase(k);else k->se -= 1;
}
void Solve() {
read(N);
for(int i = 1 ; i <= N ; ++i) read(w[i]),a[i] = w[i];
sort(a + 1,a + N + 1);
tot = unique(a + 1,a + N + 1) - a - 1;
for(int i = 1 ; i <= N ; ++i) w[i] = lower_bound(a + 1,a + tot + 1,w[i]) - a;
for(int i = 1 ; i <= N ; ++i) dp[i][w[i]] = 1;
int u;
for(int i = 2 ; i <= N ; ++i) {
read(u);
add(u,i);add(i,u);
}
dfs(1,0);
int ans = 0;
for(auto k : dp[1]) ans += k.se;
out(ans);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

最新文章

  1. LR测试登陆后进行的操作时 绕过登录
  2. hdu 5726(二分)
  3. dns简介
  4. wpf 下面用MVVC的RelayCommand命令引发的一个异常
  5. 考虑与Maya结合
  6. make_head,,,pop_head,,,push_head,,,sort_head..
  7. python的变量作用域
  8. Eclipes中使用BASE64Encoder及BASE64Decoder报错
  9. Perl时间处理函数
  10. poj 2531 Network Saboteur(经典dfs)
  11. HDU 5479 Scaena Felix
  12. Scrapy 1.4 文档 03 Scrapy 教程
  13. ES8 async/await语法
  14. DWM1000 测距原理简单分析 之 SS-TWR代码分析2 -- [蓝点无限]
  15. 转载-MySQL binlog三种模式及设置方法
  16. 003.etcd集群部署-静态发现
  17. 推荐系统模型之 FM
  18. python安装talib库
  19. hdfs结构
  20. Fibbing以让虚结点的设置更简单为目的优化网络需求

热门文章

  1. Codeforces 17.E Palisection
  2. 2018-2019 ACM-ICPC 徐州区域赛 部分题解
  3. nginx如何配置虚拟主机
  4. react-native安装react-navigation后出现package-lock.json文件的坑
  5. JavaSE的学习路线
  6. [实战篇]Tomcat发布项目-虚拟目录
  7. VS工程使用Git时的过滤文件
  8. python学习笔记(十六)之文件
  9. docker安装总结 linux红帽系列
  10. python操作上级子文件