Cod sursa(job #2952058)

Utilizator Fantastic_Mantudor voicu Fantastic_Man Data 8 decembrie 2022 10:05:45
Problema Heavy Path Decomposition Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.08 kb
#include <fstream>
#include <vector>

using namespace std;
const int nmax = 1e5;

struct Segment_tree {
    private:
    vector < int > aint;
    int N;

    int combine ( int a, int b ) {
        return a > b ? a : b;
    }

    void Update ( int node, int st, int dr, int poz, int val ) {
        if ( st == dr ) {
            aint[node] = val;
            return;
        }
        int mij = ( st + dr ) / 2;
        if ( poz <= mij )
            Update ( node + 1, st, mij, poz, val );
        else
            Update ( node + 2 * ( mij - st + 1 ), mij + 1, dr, poz, val );
        aint[node] = combine ( aint[node + 1], aint[node + 2 * ( mij - st + 1 )] );
    }

    int Query ( int node, int st, int dr, int a, int b ) {
        if ( st == a && dr == b )
            return aint[node];
        int mij = ( st + dr ) / 2;
        if ( b <= mij )
            return Query ( node + 1, st, mij, a, b );
        if ( a > mij )
            return Query ( node + 2 * ( mij - st + 1 ), mij + 1, dr, a, b );
        return combine ( Query ( node + 1, st, mij, a, mij ),
            Query ( node + 2 * ( mij - st + 1 ), mij + 1, dr, mij + 1, b ) );
    }

    public:

    void init ( int n ) {
        N = n;
        aint.resize ( 2 * N );
    }

    void update ( int poz, int val ) {
        Update ( 0, 0, N - 1, poz, val );
    }

    int query ( int st, int dr ) {
        return Query ( 0, 0, N - 1, min ( st, dr ), max ( st, dr ) );
    }
};

struct heavy {
    private:

    vector < int > parent;
    vector < int > heavy;
    vector < int > depth;
    vector < int > poz;
    vector < int > head;
    vector < int > g[nmax + 1];
    Segment_tree aint;

    int dfs ( int node, int par = -1 ) {
        int max_size = 0, size = 1;

        parent[node] = par;
        heavy[node] = -1;
        for ( int x: g[node] )
            if ( x != par ) {
                depth[x] = depth[node] + 1;
                int sz = dfs ( x, node );
                size += sz;
                if ( sz > max_size ) {
                    max_size = sz;
                    heavy[node] = x;
                }
            }
        return size;
    }

    int time = 0;
    void decompose ( int node, int par, int Head ) {
        head[node] = Head;
        poz[node] = time++;
        if ( heavy[node] != -1 )
            decompose ( heavy[node], node, Head );
        for ( int x: g[node] )
            if ( x != heavy[node] && x != par )
                decompose ( x, node, x );
    }

    public:

    void init ( int n ) {
        parent.resize ( n + 1 );
        heavy.resize ( n + 1 );
        depth.resize ( n + 1 );
        poz.resize ( n + 1 );
        head.resize ( n + 1 );
        aint.init ( n );
    }

    void add_edge ( int x, int y ) {
        g[x].push_back ( y );
        g[y].push_back ( x );
    }

    void update ( int node, int val ) {
        aint.update ( poz[node], val );
    }

    int query ( int a, int b ) {
        int ans = 0;
        while ( head[a] != head[b] ) {
            if ( depth[head[a]] < depth[head[b]] )
                swap ( a, b );
            ans = max ( ans, aint.query ( poz[a], poz[head[a]] ) );
            a = parent[head[a]];
        }
        ans = max ( ans, aint.query ( poz[a], poz[b] ) );
        return ans;
    }

    void build ( int node = 1 ) {
        dfs ( node );
        decompose ( node, -1, node );
    }

} heavy;

int v[nmax + 1];

ifstream fin ( "heavypath.in" );
ofstream fout ( "heavypath.out" );

int main() {
    int n, q, x, y, t;

    fin >> n >> q;
    for ( int i = 1; i <= n; i++ )
        fin >> v[i];

    heavy.init ( n );
    for ( int i = 1; i < n; i++ ) {
        fin >> x >> y;
        heavy.add_edge ( x, y );
    }

    heavy.build ();

    for ( int i = 1; i <= n; i++ )
        heavy.update ( i, v[i] );

    for ( int i = 1; i <= q; i++ ) {
        fin >> t >> x >> y;

        if ( t == 0 )
            heavy.update ( x, y );
        else
            fout << heavy.query ( x, y ) << '\n';

    }


    return 0;
}