Cod sursa(job #956531)

Utilizator burakbugrulBurak Bugrul burakbugrul Data 3 iunie 2013 12:21:53
Problema Guvern Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.8 kb
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <set>
#include <vector>

#define fi first
#define se second
#define pb push_back

using namespace std;

typedef pair<int,int> ii;

const int MAXN=100010;

int N,cnt,res;
int ar[MAXN];
int id[MAXN];
int go[MAXN];
int pl[MAXN];
int en[MAXN];
int pre[MAXN];
int lazy[MAXN*4];

ii as[MAXN];

set<ii> s;
vector<int> way[MAXN];

void dfs( int nd ){
	
	s.insert(ii(ar[nd],nd));
	set<ii>::iterator it=s.lower_bound(ii(ar[nd]+1,0));
	id[nd]=++cnt;
	
	if( it!=s.end() )
		go[nd]=it->se;
	
	for( vector<int>::iterator it2=way[nd].begin() ; it2!=way[nd].end() ; it2++ )
		if( *it2!=pre[nd] ){
			pre[*it2]=nd;
			dfs(*it2);
		}
	
	it=s.find(ii(ar[nd],nd));
	s.erase(it);
	en[nd]=cnt;
}

void inc( int k , int b , int e , int a1 , int a2 ){
	
	if( b>a2 || e<a1 )
		return;
	
	if( b>=a1 && e<=a2 ){
		lazy[k]++;
		return;
	}
	
	inc(k*2,b,(b+e)/2,a1,a2);
	inc(k*2+1,(b+e)/2+1,e,a1,a2);
}

int query( int k , int b , int e , int pl ){
	
	if( b>pl || e<pl )
		return 0;
	if( b==e )
		return lazy[k];
	
	return query(k*2,b,(b+e)/2,pl)+query(k*2+1,(b+e)/2+1,e,pl)+lazy[k];
}

int main(){
	
	//~ freopen("guvern.in","r",stdin);
	//~ freopen("guvern.out","w",stdout);
	
	scanf(" %d",&N);
	
	for( int a,b,i=1 ; i<N ; i++ ){
		scanf(" %d %d",&a,&b);
		way[a].pb(b);
		way[b].pb(a);
	}
	
	for( int i=1 ; i<=N ; i++ ){
		scanf(" %d",ar+i);
		as[i]=ii(ar[i],i);
	}
	
	dfs(1);
	sort(as+1,as+N+1);
	
	for( int i=1 ; i<=N ; i++ )
		pl[as[i].se]=i;
	
	for( int i=1 ; i<=N ; i++ )
		if( query(1,1,N,id[as[i].se])==0 ){
			if( go[as[i].se] ){
				int tmp=query(1,1,N,id[go[as[i].se]]);
				if( tmp!=0 )
					continue;
				inc(1,1,N,id[as[i].se],en[as[i].se]);
				res++;
				i=pl[go[as[i].se]]-1;
			}
			else{
				inc(1,1,N,id[as[i].se],en[as[i].se]);
				res++;
			}
		}
	
	printf("%d\n",res);
	return 0;
}