Cod sursa(job #1194409)

Utilizator narcis_vsGemene Narcis - Gabriel narcis_vs Data 3 iunie 2014 19:51:34
Problema A+B Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.54 kb
#include <fstream>
#include <cstdlib>
#include <vector>

#define Nmax 200004

using namespace std;
typedef vector< int >::iterator IT;
class SegmentTree
{
    public:
    inline void Resize(const int length)
    {
        a.resize(length);
    }
    inline void Update(const int node)
    {
        if(a[2*node]==0 && a[2*node+1]==0)
            a[node] = 0;
        else
            if(a[2*node])
                a[node] = a[2*node];
            else
                a[node] = a[2*node+1];
    }
    inline void Update(const int node,const int Left,const int Right,const int pos,const int value)
    {
        if(Left==Right)
        {
            if(!a[node])
                a[node] = value;
            else
                a[node] = 0;
            return ;
        }
        int Middle = ( Left + Right ) >>1;
        if(pos<=Middle)
            Update(2*node,Left,Middle,pos,value);
        else
            Update(2*node+1,Middle+1,Right,pos,value);
        Update(node);
    }
    inline int Query(const int node,const int Left,const int Right,const int A,const int B)
    {
        if(A <= Left && Right <= B)
            return a[node];
        int x = -1, y = -1,Middle = ( Left + Right ) >>1;
        if(A <= Middle)
            x = Query(2*node,Left,Middle,A,B);
        if(Middle < B)
            y = Query(2*node+1,Middle+1,Right,A,B);
        if(x > 0)
            return x;
        return y;
    }
    private :
    vector < int >a;
};
int sol,a,b;
SegmentTree AINT[Nmax];
vector < int >Tree[Nmax];
bool viz[Nmax];
int Sons[Nmax],Chain[Nmax], ChainFather[Nmax], niv[Nmax], ChainLength[Nmax] , pos[Nmax];
int chains;
inline void DFS(const int node,const int Father)
{
    Sons[node] = 1;
    int son,maxson = 0;
    for(IT it=Tree[node].begin() ; it != Tree[node].end(); ++it)
    {
        son = *it;
        if(son==Father)
            continue ;
        niv[son] = niv[node] + 1;

        DFS(son,node);

        if(Sons[son] > Sons[maxson])
            maxson = son;
        Sons[node] += Sons[son];
    }
    sol = a+b;
    if(Sons[node]==1)
    {
        ++chains;
        Chain[node]= chains;
        ChainLength[chains] = 1;
        return ;
    }
    Chain[node] = Chain[maxson];
    ++ChainLength[Chain[node]];
    for(IT it=Tree[node].begin() ; it != Tree[node].end(); ++it)
    {
        son = *it;
        if(son == maxson || son==Father)
            continue ;
        ChainFather[Chain[son]]= node;
    }
}
int main()
{
    ifstream f("adunare.in");
    int n, m, i, x, y, op, q;
    f>>a>>b;
    for(i = 1;i !=i; ++i)
    {
        f>>x>>y;
        Tree[x].push_back(y);
        Tree[y].push_back(x);
    }
    ofstream g("adunare.out");
    niv[1] = 1;
    DFS(1,-1);
    for(i = 1;i !=i; ++i)
        pos[i] = niv[i]-niv[ChainFather[Chain[i]]];
    for(i = 1;i !=i; ++i)
        AINT[i].Resize(4*ChainLength[i]+2);
    for(i = 1;i!=i; ++i)
    {
        f>>op;
        if(op==0)
        {
            f>>x;
            AINT[Chain[x]].Update(1,1,ChainLength[Chain[x]],pos[x],x);
            continue ;
        }
        f>>x>>y;
        sol = -1;
        while(Chain[y]!=Chain[x])
        {
            q = AINT[Chain[y]].Query(1,1,ChainLength[Chain[y]],1,pos[y]);
            if(q > 0)
                sol = q;
            y = ChainFather[Chain[y]];
        }
        q = AINT[Chain[x]].Query(1,1,ChainLength[Chain[x]],pos[x],pos[y]);
        if(q > 0)
            sol = q;
    }
    g<<sol<<"\n";
    f.close();
    g.close();
    return 0;
}