1. 程式人生 > >POJ 3580.SuperMemo

POJ 3580.SuperMemo

return down algo sta rand name ace pri amp

果斷寫了個 FHQ Treap……
犯了一些奇怪的錯誤……

  1. 一開始更新結點信息寫錯了。
  2. 標記下推的時候忘了左右子節點不存在的情況。

代碼:

#include <cstdio>
#include <algorithm>
#include <cstdlib>
#define ls(p) tree[p].lson
#define rs(p) tree[p].rson
using namespace std;
const int N = 1e5;
const int M = 1e5;
int n,m;
struct node
{
    int val,rnd,min,add,rev,sz;
    int lson,rson;
} tree[N + M + 10];
inline int new_node(int v)
{
    static int tot = 0;
    tree[++tot].val = tree[tot].min = v;
    tree[tot].rnd = rand();
    tree[tot].sz = 1;
    return tot;
}
inline void up(int p)
{
    tree[p].sz = tree[ls(p)].sz + 1 + tree[rs(p)].sz;
    tree[p].min = min(tree[p].val,min(tree[ls(p)].min,tree[rs(p)].min));
}
inline void down(int p)
{
    if(tree[p].add)
    {
        if(ls(p))
            tree[ls(p)].val += tree[p].add,tree[ls(p)].min += tree[p].add,tree[ls(p)].add += tree[p].add;
        if(rs(p))
            tree[rs(p)].val += tree[p].add,tree[rs(p)].min += tree[p].add,tree[rs(p)].add += tree[p].add;
        tree[p].add = 0;
    }
    if(tree[p].rev)
    {
        swap(ls(p),rs(p));
        if(ls(p))
            tree[ls(p)].rev ^= 1;
        if(rs(p))
            tree[rs(p)].rev ^= 1;
        tree[p].rev = 0;
    }
}
int merge(int x,int y)
{
    if(!x || !y)
        return x + y;
    down(x),down(y);
    if(tree[x].rnd < tree[y].rnd)
    {
        rs(x) = merge(rs(x),y);
        up(x);
        return x;
    }
    else
    {
        ls(y) = merge(x,ls(y));
        up(y);
        return y;
    }
}
void split(int p,int k,int &x,int &y)
{
    if(!p)
    {
        x = y = 0;
        return ;
    }
    down(p);
    if(tree[ls(p)].sz < k)
        x = p,split(rs(p),k - tree[ls(p)].sz - 1,rs(p),y);
    else
        y = p,split(ls(p),k,x,ls(p));
    up(p);
}
int p,x,y,z,xx,yy;
int main()
{
    tree[0].min = 0x3f3f3f3f;
    srand(20070119);
    scanf("%d",&n);
    int v;
    for(register int i = 1;i <= n;++i)
        scanf("%d",&v),p = merge(p,new_node(v));
    scanf("%d",&m);
    char op[10];
    int a,b,c;
    while(m--)
    {
        scanf("%s",op);
        if(op[0] == 'A')
        {
            scanf("%d%d%d",&a,&b,&c);
            split(p,b,x,z);
            split(x,a - 1,x,y);
            tree[y].val += c,tree[y].min += c,tree[y].add += c;
            p = merge(merge(x,y),z);
        }
        else if(op[0] == 'R' && op[3] == 'E')
        {
            scanf("%d%d",&a,&b);
            split(p,b,x,z);
            split(x,a - 1,x,y);
            tree[y].rev ^= 1;
            p = merge(merge(x,y),z);
        }
        else if(op[0] == 'R' && op[3] == 'O')
        {
            scanf("%d%d%d",&a,&b,&c);
            int len = b - a + 1;
            c %= len;
            split(p,b,x,z);
            split(x,a - 1,x,y);
            split(y,len - c,xx,yy);
            p = merge(merge(x,merge(yy,xx)),z);
        }
        else if(op[0] == 'I')
        {
            scanf("%d%d",&a,&b);
            split(p,a,x,y);
            p = merge(merge(x,new_node(b)),y);
        }
        else if(op[0] == 'D')
        {
            scanf("%d",&a);
            split(p,a,x,z);
            split(x,a - 1,x,y);
            p = merge(x,z);
        }
        else
        {
            scanf("%d%d",&a,&b);
            split(p,b,x,z);
            split(x,a - 1,x,y);
            printf("%d\n",tree[y].min);
            p = merge(merge(x,y),z);
        }
    }
}

POJ 3580.SuperMemo