Cod sursa(job #974106)

Utilizator CosminRusuCosmin Rusu CosminRusu Data 16 iulie 2013 14:51:19
Problema Heavy Path Decomposition Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.87 kb
#include <fstream>
#include <vector>
#include <bitset>
#include <queue>
#include <algorithm>
#include <utility>
#include <string.h>

using namespace std;

ifstream cin("heavypath.in");
ofstream cout("heavypath.out");


const int MAXN = 100005;
const int oo = (1<<31)-1;

typedef vector<int> Graph[MAXN];
typedef vector<int> :: iterator It;

Graph G, P;
int N, M; /// Vertices and Queries
int V[MAXN], SubArb[MAXN], Paths = 1, Pos[MAXN], Where[MAXN], Parent[MAXN], Level[MAXN], Arb[MAXN*4];
bitset<MAXN> isFree;

struct ClassComp{
    inline bool operator () (const int &a, const int &b) const{
        return SubArb[a] > SubArb[b];
    }
};

inline void DFs(int Node, int Father){
    SubArb[Node] = 1;
    Level[Node] = Level[Father] + 1;
    for(It it = G[Node].begin() , fin = G[Node].end() ; it != fin ; ++ it){
        if(*it == Father)
            continue;
        DFs(*it, Node);
        SubArb[Node] += SubArb[*it];
    }
}

inline void HeavyPath(int Node, int Father, int Path){
    Where[Node] = Path;
    for(It it = G[Node].begin(), fin = G[Node].end(); it != fin ; ++ it){
        if(*it == Father)
            continue;
        if(!isFree[*it]){
            isFree[*it] = true;
            HeavyPath(*it, Node, Path);
        }
        else {
            ++Paths;
            Parent[Paths] = Node;
            HeavyPath(*it, Node, Paths);
        }
    }
}

inline void Update(int Node, int Left, int Right, int Pos, int Val, int Delta){
    if(Left == Right){
        Arb[Node + Delta] = Val;
        return;
    }
    int mid = (Left + Right) >> 1;
    if(Pos <= mid)
        Update(2*Node, Left, mid, Pos, Val, Delta);
    else Update(2*Node + 1, Left, mid+1, Pos, Val, Delta);
    Arb[Node + Delta] = max(Arb[2*Node+Delta] , Arb[2*Node+1+Delta]);
}

inline void MakePath(){
    DFs(1, 0);
    for(int i = 1 ; i <= N ; ++ i)
        sort(G[i].begin(), G[i].end() , ClassComp());
    HeavyPath(1, 0, 1);
    for(int i = 1 ; i <= Paths ; ++ i){
        if(i > 1)
            Pos[i] = Pos[i-1] + P[i-1].size() * 4;
    for(It it = G[i].begin(), fin = G[i].end() ; it != fin ; ++ it)
            Update(1, 1, (int)P[i].size() , Level[*it] - Level[Parent[Where[*it]]], V[*it], Pos[i]);
    }
}


int query(int nod, int left, int right, int qleft, int qright, int decalaj)
{
    if(qleft <= left && right <= qright)
        return Arb[nod + decalaj];
    int mid = (left+right)/2, rez = 0;
    if(qleft <= mid)
        rez = max(rez, query(nod * 2, left, mid, qleft, qright, decalaj));
    if(mid < qright)
        rez = max(rez, query(nod * 2 + 1, mid + 1, right, qleft, qright, decalaj));
    return rez;
}

int main() {
    cin >> N >> M;
    for(int i = 1 ; i <= N ; ++ i)
        cin >> V[i];
    for(int i = 1 ; i != N ; ++ i) {
        int X, Y;
        cin >> X >> Y;
        G[X].push_back(Y);
        G[Y].push_back(X);
    }
    MakePath();
    for(int i = 1 ; i <= M ; ++ i){
        int t, x, y;
        cin >> t >> x >> y; /// those
        if(!t){
            Update(1,1,(int)P[Where[x]].size(),Level[x]-Level[Parent[Where[x]]],y,Pos[Where[x]]);
        }
        else{
                int sol=0;
        //        while(Where[x] != Where[y])
        //        {
        //            if(Level[Parent[Where[x]]]<Level[Parent[Where[y]]])
        //                swap(x,y);
        //            sol = max(sol,query(1,1,(int)P[Where[x]].size(),1,Level[x]-Level[Parent[Where[x]]],Pos[Where[x]]));
        //            x = Parent[Where[x]];
        //        }
                if ( Level[x] > Level[y] )
                  swap(x,y);
                sol = max(sol,query(1,1,(int)P[Where[x]].size(),Level[x]-Level[Parent[Where[x]]],Level[y]-Level[Parent[Where[x]]],Pos[Where[x]]));
                cout<<sol<<'\n';

        }
    }
    cout << "WORKING";
    cin.close();
    cout.close();
    return 0;
}