Cod sursa(job #1122853)

Utilizator PatrikStepan Patrik Patrik Data 25 februarie 2014 20:51:46
Problema Heavy Path Decomposition Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 4.1 kb
    #include<cstdio>
    #include<vector>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    #define NMAX 100001
    #define INF 2000000001
    #define pb push_back
    int v[NMAX] , f[NMAX] , lev[NMAX] , what_path[NMAX] , t[NMAX] , d[NMAX] , poz[NMAX];
    int N , M , dim , maxim;
    vector<int> G[NMAX] , path[NMAX] , AI[NMAX];
    bool u[NMAX];

    void read();
    void DFS(int nod , int l);
    bool comp(int a , int b)
    {
        return lev[a] < lev[b];
    }
    void update(vector<int> &A , int N , int l , int r , int poz , int val);
    void 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);
        t[1] = 1;
        for(int i = 1 ; i<= dim ; ++i ){
            sort(path[i].begin() , path[i].end() , comp);
            AI[i].resize(4*path[i].size());}
        for(int i = 1 ; i<= dim ; ++i )
            for(int j = 0 ; j <(int)path[i].size() ; ++j ){
                poz[path[i][j]] = j;
                update(AI[i],1,0,path[i].size()-1,j,v[path[i][j]]);}
       for(int i = 1 ; i<= M ; ++i )
        {
            scanf("%d%d%d" , &z , &x , &y );
            if(z == 0)
            {
                update(AI[what_path[x]],1,0,path[what_path[x]].size()-1,poz[x],y);
                v[x] = y;
            }
            else printf("%d\n" , query1(x,y));
        }
        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)
    {
        lev[nod] = l;
        if(G[nod].size() == 1 && G[nod][0] == t[nod]){
            path[++dim].pb(nod);
            what_path[nod] = dim;
            d[nod] = 1;
        }
        else
        {
            int maxx = 0 , fiu;
            for(int i = 0 ; i <(int)G[nod].size() ; ++i )
            {
                if(G[nod][i] == t[nod])continue;
                t[G[nod][i]] = nod;
                DFS(G[nod][i],l+1);
                if(maxx < d[G[nod][i]])
                {
                    maxx = d[G[nod][i]];
                    fiu = G[nod][i];
                }
                d[nod] += d[G[nod][i]];
            }
            d[nod]++;
            path[what_path[fiu]].pb(nod);
            what_path[nod] = what_path[fiu];
        }
    }

    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);
            else
                update(A,2*n+1,m+1,r,poz,val);
            A[n] = max(A[2*n],A[2*n+1]);
        }
    }

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

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