Cod sursa(job #2642132)

Utilizator MoldovanAndrei1Moldovan Andrei MoldovanAndrei1 Data 13 august 2020 19:18:42
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.01 kb
#include <bits/stdc++.h>
using namespace std;
const int NMAX = 105;
vector <int> Edge[NMAX];
int last = 0 , time1 = 0 , n;
int freq[NMAX],size_tree[NMAX],com[NMAX], parent[NMAX],value[NMAX] , Heavy_Edge[NMAX] , poz[NMAX] , start[NMAX],  aint[4*NMAX + 5];
int d[NMAX], parent1[NMAX] , height[NMAX];
void dfs(int nod)
{
    freq[nod] = 1;
    for(auto it : Edge[nod])
            if(!freq[it])
                {
                    d[it] = d[nod] + 1;
                    parent[it]=nod;
                    dfs(it);
                    size_tree[nod]+= size_tree[it];
                }
    bool ok = 0 ;
    for(auto it : Edge[nod])
            if(it!=parent[nod] && size_tree[it] >= (size_tree[nod] + 1)/2)
            {
                ok = 1;
                com[nod] = com[it];
                Heavy_Edge[it] = nod;
                break;
            }
    if(!ok)
            {
                com[nod] = ++last;
                start[last] = nod;
            }
    for(auto it: Edge[nod])
          if(it != parent[nod] && com[nod] != com[it])
            parent1[com[it]] = com[nod];
}
void dfs1(int nod)
{
    poz[++time1] = nod;
    height[nod] = time1;
    if(Heavy_Edge[nod])
      dfs1(Heavy_Edge[nod]);
}
void update(int nod ,int st , int dr , int poz,int val)
{
    if(st == dr)
        aint[nod]=val;
    else
    {
      int med = (st + dr)>>1;
      if(poz<=med)update(2*nod , st,med,poz,val);
      else
            update(2*nod + 1 , med+1,dr,poz,val);
            aint[nod]=max(aint[2*nod],aint[2*nod+1]);
    }
}
int query(int nod ,int st, int dr,int l,int r)
{
    if(l<=st&&dr<=r)
        return aint[nod];
    int med=(st+dr)>>1;
    int a = 0 ,b=0;
    if(l<=med)a=query(2*nod,st,med,l,r);
    if(r>med)
        b=query(2*nod+1,med+1,dr,l,r);
    return max(a,b);
}
int lca(int a , int b)
{
    if(a == b)return a;
    if(d[a] >= d[b])return lca(parent[a] , b);
    return lca(a , parent[b]);
}

int answer(int x , int y)
{
    if(d[x] > d[y]) swap(x , y);
    int x1 = com[x] , y1 = com [y];
    if(x1 == y1)
        return query(1 , 1 , n, min(height[x] , height[y]), max(height[x] , height[y]));
}
void solve(int x , int y)
{
    printf("%d\n",answer(x,y));
}
int main()
{
    freopen("heavypath.in","r",stdin);
    freopen("heavypath.out","w",stdout);
    int  q , i , x , y, op;
    scanf("%d%d" , &n , &q);
    for( i = 1 ; i <= n; i++)
           {
               scanf("%d", &value[i]);
               size_tree[i] = 1;
           }
    for( i = 1 ; i < n; i++)
    {
        scanf("%d%d",&x ,&y);
        Edge[x].push_back(y);
        Edge[y].push_back(x);
    }
    d[1] = 1;
    parent[1] = 1;
    dfs(1);
    for(i = 1 ; i <=last ; i++)
            dfs1(start[i]);
    for(i = 1 ; i <= n ; i++)
        update(1 , 1 , n , i , value[poz[i]]);
    for(i = 1 ; i <= q; i++)
    {
        cin >> op >> x >> y;
        if(op == 0)
            update(1 , 1 , n , height[x] , y);
        else
            solve(x,y);
    }
    return 0;
}