萌新板子样例不过求条
查看原帖
萌新板子样例不过求条
1004065
xuduang楼主2024/8/9 22:50

rt/kk

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 8e6 + 10;
int n, m, bin[N], ch[N][3], root[N];
int val[N], cnt, ck;
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;
}
int newnd(){return (cnt ? bin[cnt--] : ++ck);}
void del(int u)
{
    bin[++cnt] = u, ch[u][0] = ch[u][1] = val[u] = 0;
    return ;
}
void change(int &u, int l, int r, int x, int v)
{
    if(!u) u = newnd();
    val[u] += v;
    if(l == r) return ;
    int mid = (l + r) >> 1;
    if(x <= mid) change(ch[u][0], l, mid, x, v);
    else change(ch[u][1], mid + 1, r, x, v);
    return ;
}
int query(int u, int l, int r, int L, int R)
{
    if(R < l || r < L) return 0;
    if(L <= l && r <= R) return val[u];
    int mid = (l + r) >> 1;
    return query(ch[u][0], l, mid, L, R) + query(ch[u][1], mid + 1, r, L, R);
}
int kth(int u, int l, int r, int k)
{
    if(l == r) return l;
    int mid = (l + r) >> 1;
    if(val[ch[u][0]] >= k) return kth(ch[u][0], l, mid, k);
    else return kth(ch[u][1], mid + 1, r, k - val[ch[u][0]]);
}
int merge(int x, int y)
{
    if(!x || !y) return x + y;
    val[x] += val[y];
    ch[x][0] = merge(ch[x][0], ch[y][0]);
    ch[x][1] = merge(ch[x][1], ch[y][1]);
    del(y);
    return x;
}
void split(int x, int &y, int k)
{
    if(x == 0) return ;
    y = newnd();
    int v = val[ch[x][0]];
    if(k > v) split(ch[x][1], ch[y][1], k - v);
    else swap(ch[x][1], ch[y][1]);
    if(k < v) split(ch[x][0], ch[y][0], k);
    val[y] = val[x] - k;
    val[x] = k;
    return ;
}
int t1, t2;
int rtn;
signed main()
{
    n = read(), m = read();
    for(int i = 1; i <= n; i++) change(root[1], 1, n, i, read());
    for(int i = 1; i <= m; i++)
    {
        int opt = read();
        int x = read(), y = read(), z;
        if(opt == 0)
        {
            z = read();
            t1 = query(root[x], 1, n, 1, z);
            t2 = query(root[x], 1, n, y, z);
            int now = 0;
            split(root[x], root[++rtn], t1 - t2);
            split(root[rtn], now, t2);
            root[x] = merge(root[x], now);
        }
        if(opt == 1) root[x] = merge(root[x], root[y]);
        if(opt == 2) change(root[x], 1, n, read(), y);
        if(opt == 3) printf("%lld\n", query(root[x], 1, n, y, read()));
        if(opt == 4)
        {
            if(val[root[x]] < y)
            {
                printf("-1\n");
                continue;
            }
            printf("%lld\n", kth(root[x], 1, n, y));
        }
    }
    return 0;
}
2024/8/9 22:50
加载中...