Cod sursa(job #3232855)

Utilizator unomMirel Costel unom Data 1 iunie 2024 18:35:53
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 6.39 kb
#include <fstream>
#include <vector>
#include <cmath>

using namespace std;

ifstream in("heavypath.in");
ofstream out("heavypath.out");
int n, m, q, cnt, nr;
int p[100005];
vector<int> v[100005];
pair<int, int> euler[200005];
int viz[100005];
int first[100005];
//int rmq[18][200005];
int w[100005];
int lant[100005];
int roof[100005];
int sz[100005];
int loc[100005];
//vector<int> segtree[100005];
//vector<int> inv[100005];

void dfs(int node, int nivel)
{
    cnt++;
    euler[cnt] = {node, nivel};
    viz[node] = 1;
    w[node] = 1;

    int wmax = -1;
    int poz = -1;

    for(auto it: v[node])
    {
        if(viz[it] == 0)
        {
            dfs(it, nivel + 1);

            w[node] += w[it];
            roof[lant[it]] = node;

            if(w[it] > wmax)
            {
                wmax = w[it];
                poz = it;
            }

            cnt++;
            euler[cnt] = {node, nivel};
        }
    }

    //out<<node<<" "<<w[node]<<'\n';

    if(wmax == -1)
    {
        nr++;
        lant[node] = nr;

        sz[nr] = 1;
        loc[node] = 1;
    }
    else
    {
        lant[node] = lant[poz];

        sz[lant[node]]++;
        loc[node] = sz[lant[node]];
    }
}

/*void build_rmq()
{
    int put = 1;

    for(int i = 1; i<=m; i++)
    {
        if(i == 1)
        {
            for(int j = 1; j<=cnt; j++)
            {
                rmq[i][j] = j;
            }
        }
        else
        {
            for(int j = 1; j<=cnt-put+1; j++)
            {
                if(euler[rmq[i - 1][j]].second <= euler[rmq[i - 1][j + (put / 2)]].second)
                {
                    rmq[i][j] = rmq[i - 1][j];
                }
                else
                {
                    rmq[i][j] = rmq[i - 1][j + (put / 2)];
                }
            }
        }

        put *= 2;
    }
}

int query_rmq(int x, int y)
{
    x = first[x];
    y = first[y];

    if(x > y)
    {
        swap(x, y);
    }

    int l = y - x + 1;
    int k = log2(l);

    int m1 = rmq[k + 1][x];

    int r = l - (1 << k);

    int m2 = rmq[k + 1][x + r];

    if(euler[m1].second <= euler[m2].second)
    {
        return euler[m1].first;
    }
    else
    {
        return euler[m2].first;
    }
}

void build_segtree(int tree, int node, int left, int right)
{
    if(left == right)
    {
        segtree[tree][node] = p[inv[tree][left]];
    }
    else
    {
        int mij = (left + right) / 2;

        build_segtree(tree, 2*node, left, mij);
        build_segtree(tree, 2*node+1, mij + 1, right);

        segtree[tree][node] = max(segtree[tree][2*node], segtree[tree][2*node + 1]);
    }
}

void update_segtree(int tree, int node, int left, int right, int poz, int val)
{
    if(left == right)
    {
        segtree[tree][node] = val;
    }
    else
    {
        int mij = (left + right) / 2;

        if(poz <= mij)
        {
            update_segtree(tree, 2*node, left, mij, poz, val);
        }
        else
        {
            update_segtree(tree, 2*node+1, mij+1, right, poz, val);
        }

        segtree[tree][node] = max(segtree[tree][2*node], segtree[tree][2*node + 1]);
    }
}

int query_segtree(int tree, int node, int left, int right, int qleft, int qright)
{
    if(qleft <= left && right <= qright)
    {
        return segtree[tree][node];
    }
    else
    {
        int mij = (left + right) / 2;

        if(qright <= mij)
        {
            return query_segtree(tree, 2*node, left, mij, qleft, qright);
        }
        else if(mij + 1 <= qleft)
        {
            return query_segtree(tree, 2*node+1, mij + 1, right, qleft, qright);
        }

        return max(query_segtree(tree, 2*node, left, mij, qleft, qright), query_segtree(tree, 2*node+1, mij + 1, right, qleft, qright));
    }
}

int query(int a, int b)
{
    int x = a;
    int y = b;
    int ans = -1;

    while(1)
    {
        if(lant[x] == lant[y])
        {
            int st = min(loc[x], loc[y]);
            int dr = max(loc[x], loc[y]);

            ans = max(ans, query_segtree(lant[y], 1, 1, sz[lant[y]], st, dr));

            break;
        }
        else
        {
            ans = max(ans, query_segtree(lant[y], 1, 1, sz[lant[y]], 1, loc[y]));

            y = roof[lant[y]];
        }
    }

    return ans;
}*/

int main()
{
    in>>n>>q;

    for(int i = 1; i<=n; i++)
    {
        in>>p[i];
    }

    int x, y;
    for(int i = 1; i<n; i++)
    {
        in>>x>>y;

        v[x].push_back(y);
        v[y].push_back(x);
    }

    /*dfs(1, 1);

    //le fac crescatoare
    for(int i = 1; i<=n; i++)
    {
        loc[i] = sz[lant[i]] - loc[i] + 1;
    }

    //out<<cnt;

    m = log2(cnt) + 1;

    for(int i = 1; i<=cnt; i++)
    {
        if(first[euler[i].first] == 0)
        {
            first[euler[i].first] = i;
        }
    }*/

    //build_rmq();

    //out<<query_rmq(5, 8);

    /*out<<nr<<'\n';
    for(int i = 1; i<=n; i++)
    {
        out<<lant[i]<<" ";
    }
    out<<'\n';
    for(int i = 1; i<=nr; i++)
    {
        out<<sz[i]<<" ";
    }
    out<<'\n';
    for(int i = 1; i<=n; i++)
    {
        out<<loc[i]<<" ";
    }
    out<<'\n';
    for(int i = 1; i<=nr; i++)
    {
        out<<roof[i]<<" ";
    }*/

    for(int i = 1; i<=nr; i++)
    {
        //segtree[i].resize(4 * sz[i] + 5);
        //inv[i].resize(sz[i] + 5);
    }

    for(int i = 1; i<=n; i++)
    {
        //inv[lant[i]][loc[i]] = i;
    }

    for(int i = 1; i<=nr; i++)
    {
        //build_segtree(i, 1, 1, sz[i]);
    }

    /*int t;
    while(q--)
    {
        in>>t>>x>>y;

        if(t == 0)
        {
            update_segtree(lant[x], 1, 1, sz[lant[x]], loc[x], y);
        }
        else
        {
            if(lant[x] == lant[y])
            {
                //out<<x<<" "<<y<<" -> ";

                int st = min(loc[x], loc[y]);
                int dr = max(loc[x], loc[y]);

                out<<query_segtree(lant[x], 1, 1, sz[lant[x]], st, dr)<<'\n';
            }
            else
            {
                int lca = query_rmq(x, y);

                //out<<lca<<" ";

                int ans = max(query(lca, x), query(lca, y));

                out<<ans<<'\n';
            }
        }
    }*/

    return 0;
}