Cod sursa(job #1895592)

Utilizator badea_adi1999Badea Adrian Catalin badea_adi1999 Data 28 februarie 2017 03:33:59
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.15 kb
#include <fstream>
#include <vector>
#include <algorithm>
#define nmax 100005
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
vector <int> v[nmax],l[nmax];
int niv[nmax],viz[nmax],w[nmax],t[nmax];
int n,m,k,p[nmax],d[nmax],aint[nmax*4];
int lant[nmax],minniv[nmax],nl;

void read()
{
    int i,j,o;
    f>>n>>m;
    for (i=1;i<=n;i++)
        f>>p[i];
    for (i=1;i<n;i++) {
        f>>j>>o;
        v[j].push_back(o);
        v[o].push_back(j);
    }
}
void dfs(int nod)
{
    int i,j,leaf=1,sol=0;
    viz[nod]=1;
    w[nod]=1;
    for (i=0;i<v[nod].size();i++) {
        j=v[nod][i];
        if (viz[j])
            continue;
        t[j]=nod;
        leaf=0;
        niv[j]=niv[nod]+1;
        dfs(j);
        w[nod]+=w[j];
        if (w[sol]<w[j])
            sol=j;
    }
    if (leaf) {
        lant[nod]=++nl;
        minniv[nl]=niv[nod];
        l[nl].push_back(nod);
        return;
    }
    lant[nod]=lant[sol];
    minniv[lant[sol]]=min(minniv[lant[sol]],niv[nod]);
    l[lant[sol]].push_back(nod);
}
void build(int nod,int st,int dr,int decalaj,int lc)
{
    if (st==dr) {
        aint[nod+decalaj]=p[l[lc][st-1]];
        return;
    }
    int mid=(st+dr)>>1;
    build(nod*2,st,mid,decalaj,lc);
    build(nod*2+1,mid+1,dr,decalaj,lc);
    aint[nod+decalaj]=max(aint[nod*2+decalaj],aint[nod*2+1+decalaj]);
}
void update(int nod,int st,int dr,int decalaj,int poz,int val)
{
    if (st==dr) {
        aint[nod+decalaj]=val;
        return;
    }
    int mid=(st+dr)>>1;
    if (poz<=mid)
        update(nod*2,st,mid,decalaj,poz,val);
    else
        update(nod*2+1,mid+1,dr,decalaj,poz,val);
    aint[nod+decalaj]=max(aint[nod*2+decalaj],aint[nod*2+1+decalaj]);
}
void makepaths()
{
    int i,j,o;
    niv[1]=1;
    dfs(1);
    for (i=1;i<=nl;i++) {
        reverse(l[i].begin(),l[i].end());
        d[i]=d[i-1]+4*l[i-1].size();
        build(1,1,l[i].size(),d[i],i);
    }
}
int query(int nod,int st,int dr,int p,int q,int decalaj)
{
    if (p<=st&&dr<=q)
        return aint[nod+decalaj];

    int s=-1<<30,mid=(st+dr)>>1;
    if (p<=mid)
        s=max(s,query(nod*2,st,mid,p,q,decalaj));
    if (q>mid)
        s=max(s,query(nod*2+1,mid+1,dr,p,q,decalaj));
    return s;
}
void solvequery()
{
    int i,o,x,y,sol;
    for (i=1;i<=m;i++) {
        f>>o>>x>>y;
        if (o==0)
            update(1,1,l[lant[x]].size(),d[lant[x]],niv[x]-minniv[lant[x]]+1,y);
        else {
            sol=0;
            while (1) {
                if (lant[x]==lant[y]) {
                    if (niv[x]>niv[y])
                        swap(x,y);
                    sol=max(sol,query(1,1,l[lant[x]].size(),niv[x]-minniv[lant[x]]+1,niv[y]-minniv[lant[y]]+1,d[lant[x]]));
                    break;
                }
                if (minniv[lant[x]]<minniv[lant[y]])
                    swap(x,y);
                sol=max(sol,query(1,1,l[lant[x]].size(),1,niv[x]-minniv[lant[x]]+1,d[lant[x]]));
                x=t[l[lant[x]][0]];
            }
            g<<sol<<'\n';
        }
    }
}
int main()
{
    read();
    makepaths();
    solvequery();

    return 0;
}