Cod sursa(job #2642068)

Utilizator MoldovanAndrei1Moldovan Andrei MoldovanAndrei1 Data 13 august 2020 16:27:00
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.27 kb
#include <cstdio>
#include <iostream>
#include<vector>
using namespace std;
const int NMAX = 25;
typedef vector<int> vi ;
typedef pair<int,int> p;
#define sd second
#define pb push_back
p vertex[NMAX];
vi edges[NMAX];
int maximum[NMAX];
int depth[NMAX];
int grad[NMAX];
int str[NMAX][NMAX];
int rad[NMAX] , poz[NMAX];
int father[NMAX];
int value[NMAX];
int tot;
int viz[NMAX];
void dfs(int nod)
{
    for(auto it : edges[nod])
    {
        if(!viz[it])
            viz[it]=nod,grad[it]=grad[nod]+1,dfs(it);
        if(it!=viz[nod])
            vertex[nod].sd += vertex[it].sd;
    }
    vertex[nod].sd++;
    bool ok = 0;
    for(auto it : edges[nod])
        if(it!=viz[nod]&&vertex[it].sd >= (vertex[nod].sd + 1)/2)
        {
            vertex[nod].first=vertex[it].first;
        str[vertex[it].first][++str[vertex[it].first][0]]=value[nod];
            depth[nod]=depth[it]+1;
            maximum[vertex[nod].first]=max(maximum[vertex[nod].first], value[nod]);
            ok = 1;
            break;
        }
    if(!ok)
    {
        vertex[nod].first=++tot;
        str[tot][++str[tot][0]]=value[nod];
        depth[nod]=1;
        maximum[vertex[nod].first]=max(maximum[vertex[nod].first], value[nod]);
    }
}
void dfs1(int nod)
{
    for(auto it:edges[nod])
    {
        if(it!=viz[nod])
        {
            if(vertex[it].first!=vertex[nod].first)
                father[vertex[it].first] = vertex[nod].first , rad[vertex[it].first]=depth[nod] ;
                dfs1(it);
        }
    }
}
/// clique maxima;
int aint[NMAX][4*NMAX];
void build(int st , int dr , int nod, int k)
{
    if(st == dr)
        aint[k][nod]=str[k][st];
    else
    {
        int med=(st + dr)>>1;
        build(st,med,2*nod,k);
        build(med+1,dr,2*nod+1,k);
        aint[k][nod]=max(aint[k][2*nod],aint[k][2*nod+1]);
    }

}
/*
void update(int st,int dr,int nod, int poz , int val, int k)
{
    if(st == dr)aint[k][nod]=val;
    else
    {
        int med=(st+dr)>>1;
        if(poz<=med)update(st,med,2*nod,poz,val,k);
        else
            update(med+1,dr,2*nod+1,poz,val,k);
        aint[k][nod]=max(aint[k][2*nod],aint[k][2*nod+1]);
    }
}*/
int query(int st, int dr, int nod, int l, int r ,int k)
{
    if(l <= st && dr <=r)
        return aint[k][nod];
    else
    {
        int med =(st + dr)/2;
        int a = 0 , b = 0;
        if(l<=med)
            a = query(st , med,2*nod , l , r, k);
        if(r>med)
            b = query(med+1 , dr , 2*nod+1, l , r , k);
        return max(a,b);
    }
}
int lca(int a ,int b)
{
    if(a == b)return a;
    if(grad[a] > grad[b])swap(a,b);
    if(viz[b]!=a)
        return lca(a ,viz[b]);
}
int fct (int a , int b)
{
     int val_max = 0 ;
        if(grad[a] > grad[b])swap(a,b);
        int x1  = vertex[a].first , x2 = vertex[b].first;
        if(x1 == x2)
            return query(1,str[x1][0],1 ,min(depth[a],depth[b]),max(depth[a],depth[b]) ,x1);
        else
        {
            int x3 = father[x2];
            int ant = x2;
            while(x3!=x1)
            {
                ant = x3;
                val_max=max(val_max,maximum[x3]);
                x3 = father[x3];
            }
            int sol = query(1,str[x1][0],1,rad[ant],depth[a],x1);
            int sol1= query(1,str[x2][0],1,depth[b],str[x2][0],x2);
            val_max=max(val_max,max(sol,sol1));
            return val_max;
        }
}
int main()
{
    freopen("heavypath.in","r",stdin);
    freopen("heavypath.out","w",stdout);
    int n, q, i, j, a, b , val_max=0;
    cin >> n >> q;
    for(i = 1; i<=n; i++)
        scanf("%d",&value[i]);
    for(i=1; i<n; ++i)
    {
        scanf("%d%d",&a,&b);
        edges[a].pb(b);
        edges[b].pb(a);
    }
    grad[1]=1 , viz[1] = 1;
    dfs(1);
    dfs1(1);
    for(i = 1 ; i<=tot;++i)
        build(1 ,str[i][0] ,1 , i);
    int op;

    for(i = 1 ; i <= q; ++i)
    {
        cin >> op >> a >> b;
        if(op == 0)
        {
            continue;
            int x1 = vertex[a].first;
            //update(1,str[x1][0] , 1 , depth[a] , b , x1);
            continue;
        }
        int lca1=lca(a,b);
        int sol1=fct(a,lca1),sol2=fct(b,lca1);
        cout<<max(sol1,sol2)<<endl;
        }
    return 0;
}