kruskal重构树+主席树求条
  • 板块P4197 Peaks
  • 楼主_xxxxx_
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/10/15 19:38
  • 上次更新2024/10/15 21:18:00
查看原帖
kruskal重构树+主席树求条
664034
_xxxxx_楼主2024/10/15 19:38

快改成和 tj 一样了 qwq

#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
    int s = 0, w = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9'){if(ch == '-'){w = -1;} ch = getchar();}
    while(ch >= '0' && ch <= '9'){s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar();}
    return s * w;
}
const int N = 2e5 + 10;
const int M = 5e5 + 10;

int n, m, q;
struct node
{
    int x, y, z;
}E[M];
bool cmpE(node a, node b){return a.z < b.z;}
struct HHH
{
    int h, id;
}H[N];
bool cmpH(HHH a, HHH b){return a.h < b.h;}
int head[N], to[N * 4], ne[N * 4], id;
void add(int x, int y){to[++id] = y, ne[id] = head[x], head[x] = id;}
int val[N * 4];
int h[N];

int fa[N][22];
int find(int x){return (fa[x][0] == x ? x : fa[x][0] = find(fa[x][0]));}
int ck;
void kruskal()
{
    sort(E + 1, E + m + 1, cmpE);
    for(int i = 1; i <= n; i++) fa[i][0] = i;
    ck = n;
    for(int i = 1; i <= m; i++)
    {
        int x = E[i].x, y = E[i].y;
        int fx = find(x), fy = find(y);
        if(fx == fy) continue;
        val[++ck] = E[i].z;
        fa[fx][0] = fa[fy][0] = fa[ck][0] = ck;
        add(ck, x);
        add(ck, y);
    }
}
int cnt;
int lm[N], rm[N];
int B[N];
void dfs(int u, int faa)
{
    fa[u][0] = faa;
    for(int i = 1; i <= 20; i++) fa[u][i] = fa[fa[u][i - 1]][i - 1];
    lm[u] = cnt;
    if(!head[u]){B[++cnt] = u; rm[u] = cnt; return ;}
    for(int i = head[u]; i; i = ne[i]) dfs(to[i], u);
    rm[u] = cnt;
}
struct Tree
{
    int l, r, num;
}tr[N * 40];
void push_up(int u){tr[u].num = tr[tr[u].l].num + tr[tr[u].r].num;}
int root, rt[N];
void build(int &u, int l, int r)
{
    u = ++root;
    if(l == r) return ;
    int mid = (l + r) >> 1;
    build(tr[u].l, l, mid);
    build(tr[u].r, mid + 1, r);
}
void change(int &u, int v, int l, int r, int x)
{
    u = ++root;
    tr[u] = tr[v];
    if(l == r) return tr[u].num++, void();
    int mid = (l + r) >> 1;
    if(mid >= x) change(tr[u].l, tr[v].l, l, mid, x);
    else change(tr[u].r, tr[v].r, mid + 1, r, x);
    push_up(u);
}
int query(int u, int v, int l, int r, int x)
{
    int k = tr[tr[u].r].num - tr[tr[v].r].num;
    int mid = (l + r) >> 1;
    if(l == r)
    {
        if(x - (tr[u].num - tr[v].num) == 0) return l;
        return 0;
    }
    if(k >= x) return query(tr[u].r, tr[v].r, mid + 1, r, x);
    else return query(tr[u].l, tr[v].l, l, mid, x - k);
}
int fdx(int u, int x)
{
    for(int i = 20; ~i; i--) if(val[fa[u][i]] <= x) u = fa[u][i];
    return u;
}
signed main()
{
    n = read(), m = read(), q = read();
    for(int i = 1; i <= n; i++) h[i] = read(), H[i].h = h[i], H[i].id = i;
    sort(H + 1, H + n + 1, cmpH);
    for(int i = 1; i <= n; i++) h[H[i].id] = i;
    for(int i = 1; i <= m; i++) E[i].x = read(), E[i].y = read(), E[i].z = read();

    val[0] = 1e18;
    kruskal();
    for(int i = 1; i <= ck; i++) fa[i][0] = 0;

    dfs(ck, 0);

    // build(rt[0], 1, n);
    for(int i = 1; i <= cnt; i++) change(rt[i], rt[i - 1], 1, n, h[B[i]]);

    H[0].h = -1;
    while(q--)
    {
        int v = read(), x = read(), k = read();
        int tt = fdx(v, x);
        int ans = query(rt[rm[tt]], rt[lm[tt]], 1, n, k);
        cout << H[ans].h << endl;
    }
    return 0;
}
2024/10/15 19:38
加载中...