Cod sursa(job #1185021)

Utilizator narcis_vsGemene Narcis - Gabriel narcis_vs Data 14 mai 2014 20:32:39
Problema Guvern Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.99 kb
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
const int NMAX = 200004;
vector < int > Tree[NMAX];
pair < int , int > v[NMAX];
vector < int > a[NMAX];
int val[NMAX], N;
int first[NMAX];
int last[NMAX];
int dp[NMAX];
class SegmentTree{
    private:
    int a[4*NMAX];
    public:
    inline void Update(const int n,const int L,const int R,const int pos,const int val){
        if(L==R){
            a[n] = val;
            return;
        }
        int mid = (L+R)/2;
        if(pos <= mid)
            Update(2*n,L,mid,pos,val);
        else
            Update(2*n+1,mid+1,R,pos,val);
        a[n] = a[2*n+1];
        if(a[2*n])
            a[n] = a[2*n];
    }
    inline int Query(const int n,const int L,const int R,const int A,const int B){
       if(A <= L && R <= B)
            return a[n];
       int mid = (L+R)/2;
       int x = 0;
       int y = 0;
       if(A <= mid)
           x = Query(2*n,L,mid,A,B);
       if(mid < B)
           y = Query(2*n+1,mid+1,R,A,B);
       if(x)
           return x;
        return y;
    }
};
SegmentTree T;
inline void Read(){
   ifstream f("guvern.in");
   f >> N;
   for(int i = 1;i < N; ++i){
       int x ,y;
       f >> x >> y;
       Tree[x].push_back(y);
       Tree[y].push_back(x);
   }
   for(int i = 1; i <= N; ++i){
       f >> v[i].first;
       v[i].second = i;
   }
   f.close();
}
int K  = 0;
inline void DFS1(const int n,const int f){
    first[n] = ++K; 
    for(vector < int > ::iterator it = Tree[n].begin();it != Tree[n].end();++it)
        if(*it != f)
            DFS1(*it,n);
    last[n] = ++K;
}

inline void DFS(const int n,const int f){
    int x = T.Query(1,1,N,val[n],N); 
    if(x)
        a[x].push_back(n);
    T.Update(1,1,N,val[n],n);
    for(vector < int > ::iterator it = Tree[n].begin();it != Tree[n].end();++it)
        if(*it != f)
            DFS(*it,n);
    T.Update(1,1,N,val[n],0);
}

inline int DP(const int n){
    if(a[n].empty())
        return dp[n] = 1;
    if(dp[n])
        return dp[n];
    dp[n] = 1;
    vector < vector < int > > v;
    int x = 0;
    int maxx = 0;
    for(vector < int > ::iterator it = a[n].begin();it!=a[n].end(); ++it){
        int y = DP(*it);
        if(!x)
            x = *it;
        if(first[x] <= first[*it] && last[*it] <= last[x])
            maxx = max(maxx,y);
        else{
            x = *it;
            dp[n] += maxx;
            maxx = 0;
        }
    }
    dp[n] += maxx;
    return dp[n];
}

inline void Solve(){
    sort(v+1,v+N+1);
    int k = 0;
    for(int i = 1;i <= N; ++i)
        val[v[i].second] = ++k;
    DFS1(1,0);
    DFS(1,0);
    int sol = 0;
    for(int i = 1;i <= N; ++i)
        sol = max(sol,DP(i));
    ofstream g("guvern.out");
    g<<sol<<"\n";
    /*for(int i = 1;i <= N;++i)
        g<<dp[i]<<" ";
    g<<"\n";
    for(int i = 1;i <= N; ++i){
        g<<i<<" : ";
        for(vector < int > ::iterator it = a[i].begin();it != a[i].end();++it)
            g<<*it<<" ";
        g<<"\n";
    }*/
    g.close();
}

int main(){
    Read();
    Solve();
    return 0;
}