Cod sursa(job #2382845)

Utilizator PredaBossPreda Andrei PredaBoss Data 18 martie 2019 18:33:57
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.11 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
int n,m,x,y,counter,t,now,l,r,v;
int val[100005];
vector<int>nod[100005];
int heigth[100005];
int child[100005];
int who[100005];
int nxt[100005];
int sz[100005];
int path[100005];
int inc[100005];
int parent[100005];
int elem[100005];
vector<int>ain_path[100005];
void dfs(int pos,int last)
{
    child[pos]=1;
    int mx=0;
    for(int i=0;i<nod[pos].size();i++)
        if(nod[pos][i]!=last)
        {
            dfs(nod[pos][i],pos);
            child[pos]+=child[nod[pos][i]];
            if(child[nod[pos][i]]>mx)
            {
                mx=child[nod[pos][i]];
                who[pos]=nod[pos][i];
            }
        }
}
void go_visit(int pos,int p,int h,int last)
{
    path[pos]=p;
    elem[p]=pos;
    sz[p]++;
    heigth[pos]=h;
    bool ok=true;
    if(last==0 && nod[pos].size()>1)ok=false;
    if(last!=0 && nod[pos].size()>2)ok=false;
    for(int i=0;i<nod[pos].size();i++)
    {
        if(nod[pos][i]==last)continue;
        if(who[pos]!=nod[pos][i])
        {
            counter++;
            parent[counter]=pos;
            inc[counter]=h+1;
            go_visit(nod[pos][i],counter,h+1,pos);
        }
        else
            go_visit(nod[pos][i],p,h+1,pos);
    }
}
void modify(int pos,int st,int dr)
{
    if(l>dr || r<st)return;
    if(st==dr)
    {
        ain_path[now][pos]=v;
        return;
    }
    int mid=(st+dr)/2;
    modify(pos*2,st,mid);
    modify(pos*2+1,mid+1,dr);
    ain_path[now][pos]=max(ain_path[now][2*pos],ain_path[now][pos*2+1]);
}
int get_mx(int pos,int st,int dr)
{
    if(l>dr || r<st)return 0;
    if(l<=st && r>=dr)
        return ain_path[now][pos];
    int mid=(st+dr)/2;
    return max(get_mx(pos*2,st,mid),get_mx(pos*2+1,mid+1,dr));
}
void get_ans()
{
    int rez=0;
    int p1=path[x];
    int p2=path[y];
    while(path[x]!=path[y])
    {
        if(inc[path[x]]>inc[path[y]])swap(x,y);
        now=path[y];
        l=1;
        r=heigth[y]-inc[now]+1;
        rez=max(rez,get_mx(1,1,sz[now]));
        y=parent[now];
    }
    now=path[y];
    if(heigth[x]>heigth[y])swap(x,y);
    l=heigth[x]-inc[now]+1;
    r=heigth[y]-inc[now]+1;
    fout<<max(rez,get_mx(1,1,sz[now]))<<"\n";
}
int main()
{
    fin>>n>>m;
    for(int i=1;i<=n;i++)
       fin>>val[i];
    for(int i=1;i<n;i++)
    {
        fin>>x>>y;
        nod[x].push_back(y);
        nod[y].push_back(x);
    }
    inc[1]=0;
    counter=1;
    dfs(1,0);
    go_visit(1,1,0,0);
    for(int i=1;i<=counter;i++)
    {
        ain_path[i].resize((sz[i])*4+2);
        ain_path[i].assign((sz[i])*4+2,0);
    }
    for(int i=1;i<=n;i++)
    {
        now=path[i];
        l=r=heigth[i]-inc[now]+1;
        v=val[i];
        modify(1,1,sz[now]);
    }
    for(int i=1;i<=m;i++)
    {
        fin>>t>>x>>y;
        if(t==0)
        {
            now=path[x];
            l=r=heigth[x]-inc[now]+1;
            v=y;
            modify(1,1,sz[now]);
        }
        else
            get_ans();
    }
    return 0;
}