Cod sursa(job #2838136)

Utilizator andu2006Alexandru Gheorghies andu2006 Data 23 ianuarie 2022 10:38:41
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.1 kb
#include <bits/stdc++.h>

using namespace std;

const int NMAX=1e5+5;
vector<int> edg[NMAX];
vector<int> path[NMAX];
vector<int> segtree[NMAX];
int p[NMAX],depth[NMAX],subtreeSize[NMAX],path_id[NMAX],pos[NMAX];
int current_path;

int cost[NMAX];
void dfs(int node){
    subtreeSize[node]=1;
    int bestChild=-1,maxSubtree=0;

    for(auto it : edg[node]){
        if(it!=p[node]){
            p[it]=node,depth[it]=depth[node]+1;
            dfs(it);
            subtreeSize[node]+=subtreeSize[it];
            if(subtreeSize[it]>maxSubtree)
                maxSubtree=subtreeSize[it],bestChild=it;
        }
    }
    if(bestChild==-1)
        path_id[node]=current_path++;
    else
        path_id[node]=path_id[bestChild];

    pos[node]=path[path_id[node]].size();
    path[path_id[node]].push_back(node);
}
void Update(int id, int pathid, int val, int node, int l, int r){
    if(id<l || id>r) return;
    if(id==l && id==r){
        segtree[pathid][node]=val;
    }
    else{
        Update(id,pathid,val,node*2+1,l,(l+r)/2);
        Update(id,pathid,val,node*2+2,(l+r)/2+1,r);
        segtree[pathid][node]=max(segtree[pathid][node*2+1],segtree[pathid][node*2+2]);
    }
}
int Query(int ql, int qr, int pathid, int node, int l, int r){
    if(ql>r || qr<l) return 0;
    if(ql<=l && r<=qr) return segtree[pathid][node];
    return max(Query(ql,qr,pathid,node*2+1,l,(l+r)/2),Query(ql,qr,pathid,node*2+2,(l+r)/2+1,r));
}
int nxt_p2(int x){
    int p2=1;
    while(p2<x) p2<<=1;
    return p2;
}
int main()
{
    FILE* fin=fopen("heavypath.in","r");
    FILE* fout=fopen("heavypath.out","w");
    int n,q;
    fscanf(fin,"%d%d",&n,&q);
    for(int i=1;i<=n;i++)
        fscanf(fin,"%d",&cost[i]);
    for(int i=1;i<n;i++){
        int u,v;
        fscanf(fin,"%d%d",&u,&v);
        edg[u].push_back(v);
        edg[v].push_back(u);
    }
    dfs(1);
    for(int i=0;i<current_path;i++){
        segtree[i].resize(nxt_p2(path[i].size())*2);
    }
    for(int i=1;i<=n;i++){
        Update(pos[i],path_id[i],cost[i],0,0,path[path_id[i]].size()-1);
        /*for(auto it : segtree[path_id[i]])
            cerr<<it<<' ';
        cerr<<'\n';*/
    }
    while(q--){
        int t,u,v;
        fscanf(fin,"%d%d%d",&t,&u,&v);
        if(t==0)
            Update(pos[u],path_id[u],cost[u]=v,0,0,path[path_id[u]].size()-1);
        else{
            int ans=0;
            while(path_id[u]!=path_id[v]){
                if(depth[path[path_id[u]].back()]>depth[path[path_id[v]].back()]){
                    ans=max(ans,Query(pos[u],path[path_id[u]].size()-1,path_id[u],0,0,path[path_id[u]].size()-1));
                    u=p[path[path_id[u]].back()];
                }
                else{
                    ans=max(ans,Query(pos[v],path[path_id[v]].size()-1,path_id[v],0,0,path[path_id[v]].size()-1));
                    v=p[path[path_id[v]].back()];
                }
            }
            if(depth[u]<depth[v]) u^=v,v^=u,u^=v;
            fprintf(fout,"%d\n",max(ans,Query(pos[u],pos[v],path_id[u],0,0,path[path_id[u]].size()-1)));
        }
    }
    return 0;
}