【NOI集训】【XJ】可持久化左偏树

来源:互联网 发布:宏编程鼠标lol算开挂吗 编辑:程序博客网 时间:2024/04/29 08:07

http://hzxjhs.com:83/contest/456

果断可并堆

#include <iostream>#include <algorithm>#include <cstdio>#include <string>#include <cstring>#include <cmath>#define Rep(i, x, y) for (int i = x; i <= y; i ++)#define RepE(i, x) for (int i = pos[x]; i; i = g[i].nex)#define p t[z]#define u t[x]#define v t[y]using namespace std;typedef long long LL;const int N = 200005;struct arr { int d, w, l, r; } t[N * 100];int n, q, a[N], sz, nz, ro[N];int Merge(int x, int y) {    if (!x || !y) return x + y;    if (v.w > u.w) swap(x, y);    int z = ++ sz; p = u;    p.r = Merge(p.r, y);    if (t[p.r].d > t[p.l].d) swap(p.r, p.l);    p.d = t[p.r].d + 1;    return z;}int newd(int y) { int x = ++ sz; u.w = y; return x; }int Qry(int x, int y) {    Rep(i, 1, y - 1) {        x = Merge(u.l, u.r);    }    return u.w;}int main(){    scanf ("%d%d", &n, &q);    Rep(i, 1, n) scanf ("%d", &a[i]), ro[i] = newd(a[i]);    nz = n;    Rep(i, 1, q) {        int ty, x, y, z;        scanf ("%d", &ty);        if (ty == 1) {            scanf ("%d%d%d", &z, &x, &y);            ro[++ nz] = Merge(newd(z), Merge(ro[x], ro[y])); // c1[nz] = x, c2[nz] = y;        } else if (ty == 2) {            scanf ("%d", &x);            // Merge()        } else {            scanf ("%d%d", &x, &y);            printf ("%d\n", Qry(ro[x], y));        }    }     return 0;}


0 0
原创粉丝点击