Cod sursa(job #2935301)

Utilizator DooMeDCristian Alexutan DooMeD Data 6 noiembrie 2022 14:31:39
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.28 kb
#include <bits/stdc++.h>
using namespace std;
const int nmax = 1e5;

#include <stdio.h>
#include <ctype.h>

/** Funcţiile necesare parsării fişierului de intrare **/
FILE *_fin;
int _in_loc; char _in_buff[4096];


void read_init(const char* nume) // Apelaţi această funcţie la începutul funcţiei <main>
{
	_fin = fopen(nume, "r");
	_in_loc = 4095;
}

char read_ch()
{
	++_in_loc;
	if (_in_loc == 4096) {
		_in_loc = 0;
		fread(_in_buff, 1, 4096, _fin);
	}
	return _in_buff[_in_loc];
}

int read_u32() // Apelaţi această funcţie pentru a citi un număr ce se încadrează în categoria <unsigned int>
{
	int u32 = 0; char c;
	while (!isdigit(c = read_ch()) && c != '-');
	int sgn = 1;
	if (c == '-') {
		sgn = -1;
	} else {
		u32 = c - '0';
	}
	while (isdigit(c = read_ch())) {
		u32 = u32 * 10 + c - '0';
	}
	return u32 * sgn;
}

long long read_u64() // Apelaţi această funcţie pentru a citi un număr ce se încadrează în categoria <unsigned long long>
{
	long long u64 = 0; char c;
	while (!isdigit(c = read_ch()) && c != '-');
	long long sgn = 1;
	if (c == '-') {
		sgn = -1;
	} else {
		u64 = c - '0';
	}
	while (isdigit(c = read_ch())) {
		u64 = u64 * 10 + c - '0';
	}
	return u64 * sgn;
}

vector<vector<int>> dx(nmax+5);
int init[nmax+5], dim[nmax+5], par[nmax+5], nxt[nmax+5], niv[nmax+5];

int in[nmax+5], out[nmax+5], timer = 1, v[nmax+5];
int aint[2*nmax+5];

void dfs_dim(int node) {
    dim[node] = 1;
    for(auto &i : dx[node]) {
        dx[i].erase(find(dx[i].begin(), dx[i].end(), node));
        par[i] = node;
        niv[i] = niv[node] + 1;
        dfs_dim(i);
        dim[node] += dim[i];
        if(dim[i] > dim[dx[node][0]]) swap(i, dx[node][0]);
    }
}

void dfs_hld(int node) {
    in[node] = timer++;
    for(auto i : dx[node]) {
        nxt[i] = (i == dx[node][0] ? nxt[node] : i);
        dfs_hld(i);
    }
    out[node] = timer - 1;
}

void build(int n) {
    for(int i=1; i<=n; i++) aint[i+n-1] = v[i];
    for(int i=n-1; i>=1; i--) aint[i] = max(aint[2*i], aint[2*i+1]);
}

void update(int n, int pos, int val) {
    for(aint[pos+=n]=val; pos>1; pos/=2) aint[pos/2] = max(aint[pos], aint[pos^1]);
}

int query(int n, int st, int dr) {
    int temp = 0;
    for(st += n, dr += n; st < dr; st/=2, dr/=2) {
        if(st&1) temp = max(temp, aint[st++]);
        if(dr&1) temp = max(temp, aint[--dr]);
    }
    return temp;
}

int main() {
    read_init("heavypath.in");
    ofstream g("heavypath.out");

    int n, q; n = read_u32(); q = read_u32();
    for(int i=1; i<=n; i++) init[i] = read_u32();
    for(int i=1; i<=n-1; i++) {
        int x, y; x = read_u32(); y = read_u32(); 
        dx[x].emplace_back(y);
        dx[y].emplace_back(x);
    }
    nxt[1] = 1;
    dfs_dim(1);
    dfs_hld(1);
    for(int i=1; i<=n; i++) v[in[i]] = init[i];
    build(n);
    for(int i=1; i<=q; i++) {
        int type, a, b; type = read_u32(); a = read_u32(); b = read_u32(); 
        if(type == 0) update(n, in[a]-1, b);
        else {
            int ans = 0;
            while(nxt[a] != nxt[b]) {
                if(niv[nxt[a]] < niv[nxt[b]]) swap(a, b);
                ans = max(ans, query(n, in[nxt[a]]-1, in[a]));
                a = par[nxt[a]];
            }
            if(in[a] > in[b]) swap(a, b);
            ans = max(ans, query(n, in[a]-1, in[b]));
            g << ans << "\n";
        }
    }
    return 0;
}