题目
题解
就是说祖先要≤儿子,
找不合法的个数,就是求最多合法的个数,
设fifi长度为i的最长不下降子序列的结尾最小是什么。
对于每一个点,用multiset来维护这个f,
启发式合并。
code
#include <queue>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#include <time.h>
#include <set>
#define ll long long
#define N 200003
#define M 103
#define db double
#define P putchar
#define G getchar
#define inf 998244353
#define pi 3.1415926535897932384626433832795
using namespace std;
char ch;
void read(int &n)
{
n=0;
ch=G();
while((ch<'0' || ch>'9') && ch!='-')ch=G();
ll w=1;
if(ch=='-')w=-1,ch=G();
while('0'<=ch && ch<='9')n=(n<<3)+(n<<1)+ch-'0',ch=G();
n*=w;
}
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
ll abs(ll x){return x<0?-x:x;}
ll sqr(ll x){return x*x;}
void write(ll x){if(x<0){P('-');write(-x);return;}if(x>9) write(x/10);P(x%10+'0');}
int n,x,y,nxt[N*2],to[N*2],lst[N],tot,v[N];
multiset <int> q[N];
multiset<int>::iterator p;
void dfs(int x,int fa)
{
for(int i=lst[x];i;i=nxt[i])
{
if(to[i]==fa)continue;
dfs(to[i],x);
if(q[to[i]].size()>q[x].size())swap(q[to[i]],q[x]);
for(p=q[to[i]].begin();p!=q[to[i]].end();p++)
q[x].insert(*p);
q[to[i]].clear();
}
p=q[x].upper_bound(v[x]);
if(p!=q[x].end())q[x].erase(p);
q[x].insert(v[x]);
}
void ins(int x,int y)
{
nxt[++tot]=lst[x];
to[tot]=y;
lst[x]=tot;
}
int main()
{
freopen("simple.in","r",stdin);
freopen("simple.out","w",stdout);
read(n);
for(int i=1;i<=n;i++)
read(v[i]),v[i]=-v[i];
for(int i=1;i<n;i++)
read(x),read(y),ins(x,y),ins(y,x);
dfs(1,0);
write(n-q[1].size());
return 0;
}