Cod sursa(job #2742885)

Utilizator Sho10Andrei Alexandru Sho10 Data 22 aprilie 2021 10:21:29
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.16 kb
#include <bits/stdc++.h> //Andrei Alexandru a.k.a Sho
#define ll long long
#define double long double
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#define aint(a) (a).begin(), (a).end()
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define pi pair
#define rc(s) return cout<<s,0
#define endl '\n'
#define mod 1000000007
#define PI 3.14159265359
#define INF 1000000005
#define LINF 1000000000000000005ll
#define CODE_START  ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
ll n,q,a[200005],pos[200005],depth[200005],roof[200005],sub[200005],c[200005],col=1,sz[200005],tin[200005],tout[200005],timer=0;
vector<ll>g[200005];
vector<ll>tree[200005];
void dfs1(ll node,ll par){
ll check=1;
sub[node]=1;
tin[node]=++timer;
ll heavy=-1;
for(auto it : g[node]){
    if(it!=par){
        check=0;
        depth[it]=depth[node]+1;
        dfs1(it,node);
        sub[node]+=sub[it];
    }
}
tout[node]=++timer;
}
void dfs(ll node,ll par){
ll heavy=-1;
for(auto it : g[node]){
    if(it!=par){
        if(heavy==-1){
            heavy=it;
        }else if(sub[it]>sub[heavy]){
        heavy=it;
        }
    }
}
if(heavy==-1){
    return;
}
for(auto it : g[node]){
    if(it!=par){
if(it==heavy){
    c[it]=c[node];
    pos[it]=pos[node]+1;
    sz[c[it]]=max(sz[c[it]],pos[it]);
    dfs(it,node);
}else {
c[it]=++col;
roof[c[it]]=node;
pos[it]=1;
sz[c[it]]=1;
dfs(it,node);
}
    }
}
}
void update(ll indx,ll node,ll l,ll r,ll poss,ll val){
if(l>poss){
    return;
}
if(r<poss){
    return;
}
if(l==r){
    tree[indx][node]=val;
    return;
}
ll mid=(l+r)/2;
update(indx,2*node,l,mid,poss,val);
update(indx,2*node+1,mid+1,r,poss,val);
tree[indx][node]=max(tree[indx][node*2],tree[indx][2*node+1]);
}
ll query(ll indx,ll node,ll l,ll r,ll st,ll dr){
if(r<st){
    return 0;
}
if(l>dr){
    return 0;
}
if(st<=l&&r<=dr){
    return tree[indx][node];
}
ll mid=(l+r)/2;
return max(query(indx,2*node,l,mid,st,dr),query(indx,2*node+1,mid+1,r,st,dr));
}
bool check(ll x,ll y){
return tin[x]<=tin[y] && tout[x]>=tout[y];
}
int32_t main(){
CODE_START;
ifstream cin("heavypath.in");
ofstream cout("heavypath.out");
cin>>n>>q;
c[1]=1;
pos[1]=1;
for(ll i=1;i<=n;i++)
{
    cin>>a[i];
}
for(ll i=1;i<n;i++)
{
    ll l,r;
    cin>>l>>r;
    g[l].pb(r);
    g[r].pb(l);
}
dfs1(1,0);
dfs(1,0);
for(ll i=1;i<=col;i++)
{
    for(ll j=0;j<=100*sz[i];j++)
    {
        tree[i].pb(0);
    }
}
for(ll i=1;i<=n;i++)
{
   // cout<<c[i]<<' '<<pos[i]<<' '<<roof[c[i]]<<endl;
    update(c[i],1,1,sz[c[i]],pos[i],a[i]);
}
while(q--){
    ll type;
    cin>>type;
    if(type==1){
       ll poss,val;
       cin>>poss>>val;
 update(c[poss],1,1,sz[c[poss]],pos[poss],val);
    }else {
    ll x=1,y,yy;
    cin>>y>>yy;
      ll ans=0;
    if(check(y,yy)==0&&check(yy,y)==0){
    ll res=0;
    while(1){
            if(y==0){
                break;
            }
        if(c[x]==c[y]){
ans=max(ans,query(c[x],1,1,sz[c[x]],pos[x],pos[y]));
        }else {
        ans=max(ans,query(c[y],1,1,sz[c[y]],1,pos[y]));
        }
        if(c[x]==c[y]){
                break;
        }else {
        y=roof[c[y]];
    }

}
x=1;
y=yy;
    while(1){
            if(y==0){
                break;
            }
        if(c[x]==c[y]){
ans=max(ans,query(c[x],1,1,sz[c[x]],pos[x],pos[y]));
        }else {
        ans=max(ans,query(c[y],1,1,sz[c[y]],1,pos[y]));
        }
        if(c[x]==c[y]){
                break;
        }else {
        y=roof[c[y]];
    }

}
    }else {
    if(check(y,yy)==0){
        swap(y,yy);
    }
    x=y;
    y=yy;

while(1){
            if(y==0){
                break;
            }
        if(c[x]==c[y]){
ans=max(ans,query(c[x],1,1,sz[c[x]],pos[x],pos[y]));
        }else {
        ans=max(ans,query(c[y],1,1,sz[c[y]],1,pos[y]));
        }
        if(c[x]==c[y]){
                break;
        }else {
        y=roof[c[y]];
    }

}
    }
cout<<ans<<' ';
    }
}
}
/*
10 10
5 4 1 9 5 3 1 2 9 8
10 4
10 3
6 2
2 5
9 5
5 8
7 4
7 6
1 6
2 9
1 10 5
2 8
2 5
2 8
2 3
1 7 5
2 2
2 5
1 6 2
*/