bzoj1895

fhqtreap

其实fhqtreap只有可持久化之后才用新建节点。。。

reverse和splay一样。

//#include<bits/stdc++.h>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 200010;
int n, root, cnt, m, last;
int size[N], tag[N], a[100010], rnd[N];
int child[N][2];
ll mn[N], add[N], key[N];
void update(int x)
{
    size[x] = size[child[x][0]] + size[child[x][1]] + 1;
    mn[x] = min(key[x], min(mn[child[x][0]], mn[child[x][1]]));
}
void pushdown(int x)
{
    if(!x) return;
    if(add[x])
    {
        add[child[x][0]] += add[x];
        add[child[x][1]] += add[x];
        mn[child[x][0]] += add[x];
        mn[child[x][1]] += add[x];
        key[child[x][0]] += add[x];
        key[child[x][1]] += add[x];
        add[x] = 0;
    } 
    if(tag[x])
    {
        tag[child[x][0]] ^= 1;
        tag[child[x][1]] ^= 1;
        swap(child[x][0], child[x][1]);
        tag[x] = 0;
    }
}
int newnode(int x)
{
    ++cnt;
    size[cnt] = 1;
    rnd[cnt] = rand();
    key[cnt] = x;
    mn[cnt] = x;
    return cnt;
}
int copy(int x)
{
    ++cnt;
    size[cnt] = size[x];
    rnd[cnt] = rnd[x];
    tag[cnt] = tag[x];
    mn[cnt] = mn[x];
    add[cnt] = add[x];
    child[cnt][0] = child[x][0];
    child[cnt][1] = child[x][1];
    key[cnt] = key[x];
    return cnt;
}
int merge(int x, int y)
{
    if(!x) return y;
    if(!y) return x;
    pushdown(x); 
    pushdown(y);
    if(rnd[x] < rnd[y])
    {
        child[x][1] = merge(child[x][1], y);
        update(x);
        return x;
    }
    else
    {
        child[y][0] = merge(x, child[y][0]);
        update(y);
        return y;
    } 
} 
PII split(int x, int k)
{
    if(!x) return make_pair(0, 0);
    PII ret;
    pushdown(x);
    if(k <= size[child[x][0]])
    {
        ret = split(child[x][0], k);
        child[x][0] = ret.second;
        ret.second = x;
        update(x);
        return ret;
    }
    else
    {
        ret = split(child[x][1], k - size[child[x][0]] - 1);
        child[x][1] = ret.first;
        ret.first = x;
        update(x);
        return ret;
    }
}
void Add(int l, int r, int d)
{
    PII t1 = split(root, l - 1);
    PII t2 = split(t1.second, r - l + 1);
    key[t2.first] += d;
    add[t2.first] += d;
    mn[t2.first] += d;
    root = merge(t1.first, merge(t2.first, t2.second));
}
void reverse(int l, int r)
{
    int mid = r - l + 1;
    PII t1 = split(root, l - 1);
    PII t2 = split(t1.second, r - l + 1);
    tag[t2.first] ^= 1;
    root = merge(t1.first, merge(t2.first, t2.second));
}
void revolve(int l, int r, int t)
{
    if(t < 0) t = 0;
    t %= (r - l + 1);
    PII t1 = split(root, l - 1);
    PII t2 = split(t1.second, r - l + 1);
    PII t3 = split(t2.first, r - l + 1 - t);
    root = merge(t1.first, merge(merge(t3.second, t3.first), t2.second));
}
void ins(int x, int p)
{
    PII t1 = split(root, x);
    int a = newnode(p);
    root = merge(t1.first, merge(a, t1.second));
}
void del(int x)
{
    PII t1 = split(root, x - 1);
    PII t2 = split(t1.second, 1);
    root = merge(t1.first, t2.second);
}
void que(int l, int r)
{
    PII t1 = split(root, l - 1);
    PII t2 = split(t1.second, r - l + 1);
    printf("%lld\n", mn[t2.first]);
    root = merge(t1.first, merge(t2.first, t2.second));
}
void build(int &x, int l, int r)
{
    if(l > r) return;
    int mid = (l + r) >> 1;
    x = newnode(a[mid]);
    build(child[x][0], l, mid - 1);
    build(child[x][1], mid + 1, r);
    update(x);
}
void print(int x)
{
    if(!x) return;
    pushdown(x);
    print(child[x][0]);
    printf("%d ", key[x]);
    print(child[x][1]);
}
int main()
{
//    freopen("supermemo8.in", "r", stdin);
//    freopen("output.txt", "w", stdout);
    srand(123456);
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    mn[0] = 10000000000000ll;
    build(root, 1, n);
    scanf("%d", &m);
    while(m--)
    {
        char opt[10]; int l, r, d, x, t, p; scanf("%s", opt);
        if(opt[0] == 'A')
        {
            scanf("%d%d%d", &l, &r, &d);
            Add(l, r, d);
        }
        if(opt[2] == 'V' && opt[3] == 'E')
        {
            scanf("%d%d", &l, &r);
            reverse(l, r);
        }
        if(opt[3] == 'O')
        {
            scanf("%d%d%d", &l, &r, &t);
            revolve(l, r, t);
        }
        if(opt[0] == 'I')
        {
            scanf("%d%d", &x, &p);
            ins(x, p);
        }
        if(opt[0] == 'D')
        {
            scanf("%d", &x);
            del(x);
        }
        if(opt[0] == 'M')
        {
            scanf("%d%d", &l, &r);
            que(l, r);
        }
//        print(root);
//        puts("");
    }
//    fclose(stdin); fclose(stdout);
    return 0;
}
View Code

 

posted @ 2017-06-26 15:38  19992147  阅读(200)  评论(0编辑  收藏  举报