Cod sursa(job #2501162)

Utilizator AlexBolfaAlex Bolfa AlexBolfa Data 29 noiembrie 2019 10:02:56
Problema Heavy Path Decomposition Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.01 kb
#include <bits/stdc++.h>
#define NMAX (int)(1e5+4)
#define pb push_back
#define ft first
#define sd second
using namespace std;
FILE* fin=fopen("heavypath.in", "r");
FILE* fout=fopen("heavypath.out", "w");
typedef pair <int, int> pairINT;
typedef long long ll;
struct nod{
    int pos, chain, depth;
};
nod nd[NMAX];
int n,q,l,id,w[NMAX],v[NMAX],sub[NMAX],up[NMAX],segm[NMAX],tata[NMAX];
vector <int> g[NMAX];

void read();
void dfs(int);
void buildChain(int);
void build(int,int,int);
void update(int,int,int,int,int);
int query(int,int,int,int,int);
int queryHeavy(int,int);

int main(){
    read();
    dfs(1);
    buildChain(1); up[1]=1;
    build(1,1,n);
    int task,x,y;
    while(q--){
        fscanf(fin, "%d %d %d", &task, &x, &y);
        if(task){
            fprintf(fout, "%d\n", queryHeavy(x, y));
        }else{
            update(1,1,n,y,nd[x].pos);
        }
    }
    return 0;
}
int queryHeavy(int x,int y){
    int sol=0;
    while(nd[x].chain != nd[y].chain){
        if(nd[up[nd[x].chain]].depth > nd[up[nd[y].chain]].depth) swap(x, y);

        sol=max(sol, query(1,1,n,nd[up[nd[y].chain]].pos, nd[y].pos));
        y=tata[up[nd[y].chain]];
    }
    if(nd[x].depth > nd[y].depth) swap(x, y);
    return max(sol, query(1,1,n,nd[x].pos,nd[y].pos));
}
void dfs(int node){//build chains
    sub[node]=1;
    nd[node].depth=nd[tata[node]].depth+1;
    for(auto it:g[node])
        if(it != tata[node]){
            tata[it]=node;
            dfs(it);
            sub[node]=sub[it];
        }
}
void buildChain(int node){
    int maxi=0;
    nd[node].chain=id;
    nd[node].pos=l;
    v[l++]=node;

    for(auto it:g[node])
        if(it != tata[node] && sub[maxi] < sub[it])
            maxi=it;

    if(maxi) buildChain(maxi);
    for(auto it:g[node])
        if(it != tata[node] && it != maxi){
            ++id;
            up[id]=it;
            buildChain(it);
        }
}
int query(int node,int l,int r,int st,int dr){
    if(st<=l && r<=dr){
        return segm[node];
    }
    int mid=(l+r)>>1,sol=0;
    if(st<=mid)
        sol=max(sol, query(node<<1, l, mid, st, dr));
    if(mid<dr)
        sol=max(sol, query(node<<1 | 1, mid+1, r, st, dr));

    return sol;
}
void update(int node,int l,int r,int val,int pos){
    if(l == r){
        segm[node]=val;
        return;
    }
    int mid=(l+r)>>1;
    if(pos<=mid)
        update(node<<1, l, mid, val, pos);
    else
        update(node<<1|1, mid+1, r, val, pos);
    segm[node]=max(segm[node<<1], segm[node<<1 | 1]);
}
void build(int node,int l,int r){
    if(l == r){
        segm[node]=w[v[l]];
        return;
    }
    int mid=(l+r)>>1;
    build(node<<1,l,mid);
    build(node<<1 | 1,mid+1,r);
    segm[node]=max(segm[node<<1], segm[node<<1 | 1]);
}
void read(){
    fscanf(fin, "%d %d", &n, &q);
    for(int i=1;i<=n;++i) fscanf(fin, "%d", &w[i]);
    for(int i=1,x,y;i<n;++i){
        fscanf(fin, "%d %d", &x, &y);
        g[x].pb(y);
        g[y].pb(x);
    }
    l=id=1;
}