Cod sursa(job #1123252)

Utilizator PatrikStepan Patrik Patrik Data 25 februarie 2014 23:52:51
Problema Heavy Path Decomposition Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 4.86 kb
    #include<cstdio>
    #include<vector>
    #include<algorithm>
    using namespace std;
    #define pb push_back
    #define MAX 100001
    #define INF 2000000001
    int N , M , v[MAX] , d[MAX] , t[MAX] , dim  , lev[MAX] , w_path[MAX] , niv[MAX] , tp[MAX] ;
    int poz[MAX];
    vector<int> G[MAX] , path[MAX] , AI[MAX];

    void read();
    void DFS(int nod , int l);
    void DFS1(int nod);
    bool comp(int x , int y)
    {
        return lev[x] < lev[y];
    }
    void update(vector<int> &A,int n , int l , int r , int poz , int val);
    int query(vector<int> A,int n , int l , int r , int a , int b);
    int query1(int x , int y);

    int main()
    {
        int x , y,  z;
        read();
        DFS(1,0);
        DFS1(1);
        for(int i = 1 ; i<= dim ; ++i )
            sort(path[i].begin(),path[i].end(),comp);
        for(int i = 1 ; i<= dim ; ++i )
            AI[i].resize(path[i].size()*5);
        for(int i = 1 ; i<= dim ; ++i )
            for(int j = 0 ;  j <(int)path[i].size() ; ++j )
                poz[path[i][j]] = j;
        for(int i = 1 ; i<= N ; ++i )
            update(AI[w_path[i]],1,0,path[w_path[i]].size()-1,poz[i],v[i]);
        for(int i = 2 ; i<= N ; ++i )
            if(w_path[i] != w_path[t[i]])
                tp[w_path[i]] = t[i];
        int p = 0;
       for(; M-- && p <= 920 ; )
       {
           scanf("%d%d%d" , &z , &x , &y );
           if(z == 0)
           {
            update(AI[w_path[x]],1,0,path[w_path[x]].size()-1,poz[x],y);
            v[x] = y;
           }
           else
            printf("%d\n" , query1(x,y)),p++;;
       }
       for(; M--; )
       {
           scanf("%d%d%d" , &z , &x , &y );
           if(z == 0)
           {
            update(AI[w_path[x]],1,0,path[w_path[x]].size()-1,poz[x],y);
            v[x] = y;
           }
           else
            printf("%d\n" , query1(x,y)),p++;;
       }
        return 0;
    }

    void read()
    {
        int x , y;
        freopen("heavypath.in" , "r" , stdin );
        freopen("heavypath.out" , "w" , stdout );
        scanf("%d%d" , &N , &M );
        for(int i = 1 ; i<= N ; ++i )
            scanf("%d" , &v[i] );
        for(int i = 1 ; i< N ; ++i )
        {
            scanf("%d%d" , &x , &y );
            G[x].pb(y);
            G[y].pb(x);
        }
    }

    void DFS(int nod , int l)
    {
        int maxx = 0 , fiu;
        lev[nod] = l;
        if(G[nod].size() == 1 && G[nod][0] == t[nod])
        {
            path[++dim].pb(nod);
            w_path[nod] = dim;
            d[nod] = 1;
        }
        else
        {
            for(int i = 0 ; i <(int)G[nod].size() ; ++i )
                if(G[nod][i] != t[nod])
            {
                t[G[nod][i]] = nod;
                DFS(G[nod][i],l+1);
                if(d[G[nod][i]] > maxx)
                    {
                        maxx = d[G[nod][i]];
                        fiu =  G[nod][i];
                    }
                d[nod]+=d[G[nod][i]];
            }
            d[nod]++;
            path[w_path[fiu]].pb(nod);
            w_path[nod] = w_path[fiu];
        }
    }

    void DFS1(int nod)
    {
        for(int i = 0 ; i<(int)G[nod].size() ; ++i )
            if(G[nod][i] != t[nod])
        {
            if(w_path[nod] != w_path[G[nod][i]])
                niv[w_path[G[nod][i]]] = niv[nod] + 1;
            DFS1(G[nod][i]);
        }
    }

    void update(vector<int> &A,int n , int l , int r , int poz , int val)
    {
        if(l == r)A[n] = val;
        else
        {
            int m = (l+r)/2;
            if(poz <= m)
                update(A,2*n,l,m,poz,val);
            if(poz > m)
                update(A,2*n+1,m+1,r,poz,val);
            A[n] = max(A[2*n],A[2*n+1]);
        }
    }

    int query1(int x , int y)
    {
        int rez = max(v[x],v[y]) , aux;
        while(w_path[x] != w_path[y])
        {
            if(niv[w_path[x]] < niv[w_path[y]])
            {
                rez = max(rez,query(AI[w_path[y]],1,0,path[w_path[y]].size()-1,0,poz[y]));
                y = tp[w_path[y]];
            }
            else
            {
                rez = max(rez,query(AI[w_path[x]],1,0,path[w_path[x]].size()-1,0,poz[x]));
                x = tp[w_path[x]];
            }
        }
        if(lev[x] > lev[y]){aux = x;x=y;y=aux;}
        rez = max(rez,query(AI[w_path[x]],1,0,path[w_path[x]].size()-1,poz[x],poz[y]));
        return rez;
    }

    int query(vector<int> A , int n , int l , int r , int a , int b)
    {
        if(a <= l && b >= r )return A[n];
        else
        {
            int m = (l+r)/2;
            int maxx = -INF;
            if(a <= m)
                maxx = query(A,2*n,l,m,a,b);
            if(b > m)
                maxx = max(maxx,query(A,2*n+1,m+1,r,a,b));
            return maxx;
        }
    }