[BZOJ3506][BZOJ1552] [Cqoi2014]排序机械臂

来源:互联网 发布:c语言中删除文件 编辑:程序博客网 时间:2024/05/02 21:14

之前一直在调自己的delete 以为树写错了 结果居然离散化错了 坑坑坑坑坑 果然还是要多膜拜膜拜hlq大牛吗 


多保留一个信息Min 用Min来进行元素的查找定位删除等等 其他没啥了。。。

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;#define MAXN 100000#define INF 99999999int a[MAXN+10], T[MAXN+10], app[MAXN+10], A[MAXN+10], n;struct Node {    int key, sz, cnt, flag, Min;    Node *ch[2], *fa;    Node () {}    Node(int x, int y, int z, int M) {        key = x; sz = y; cnt = z; Min = M;    }    void Update() {        sz = ch[0]->sz + ch[1]->sz + cnt;        Min = min(key, min(ch[0]->Min, ch[1]->Min));    }    int cmp(int v) const {        if(v == key) return -1;        return v < key ? 0 : 1;    }}nil(0, 0, 0, INF), *NIL = &nil;struct Splay_Tree{    Node *root;    Node tree[MAXN+10];    int ncnt;    void init() { root = NIL; ncnt = 0 ;};    Node *NewNode() {        Node &t = tree[++ncnt];        t.ch[0] = t.ch[1] = t.fa = NIL;        t.sz = t.cnt = 1;        t.flag = 0;        return &tree[ncnt];    }    void pushdown(Node *target) {        if(target->flag)        {            target->flag = 0;            swap(target->ch[0], target->ch[1]);            if(target->ch[0] != NIL) target->ch[0]->flag ^= 1;            if(target->ch[1] != NIL) target->ch[1]->flag ^= 1;        }    }    void Rotate(Node *x, int d)    {        Node *y = x->fa;        y->ch[!d] = x->ch[d];        if(x->ch[d] != NIL) x->ch[d]->fa = y;        x->fa = y->fa;        if(y->fa != NIL) y->fa->ch[y->fa->ch[1] == y] = x;        x->ch[d] = y;        y->fa = x;        if(y == root) root = x;        y->Update();        x->Update();    }    void splay(Node *x, Node *target)    {        Node *y, *z;        while(x->fa != target)        {            pushdown(x);            y = x->fa; y->Min = y->key;            z = y->fa; if(z != NIL) z->Min = z->key;            if(z == target) {                if(x == y->ch[0]) Rotate(x, 1);                else Rotate(x, 0);            }            else            {                if(y == z->ch[0])                    if(x == y->ch[0])                        Rotate(y, 1), Rotate(x, 1);                    else                        Rotate(x, 0), Rotate(x, 1);                else                    if(x == y->ch[1])                        Rotate(y, 0), Rotate(x, 0);                    else                        Rotate(x, 1), Rotate(x, 0);            }            x->Update();        }        pushdown(x);    }    int Find_rank(Node * target, int key)    {        pushdown(target);        if(key == target->key) return target->ch[0]->sz + 1;        if(key == target->ch[0]->Min) return Find_rank(target->ch[0], key);        return target->ch[0]->sz + 1 + Find_rank(target->ch[1], key);    }    Node *Find_kth(Node * target, int k)    {        pushdown(target);        if(k <= target->ch[0]->sz) return Find_kth(target->ch[0], k);        if(k <= target->ch[0]->sz+1) return target;        return Find_kth(target->ch[1], k-target->ch[0]->sz-1);    }    void Del(int X)    {        if(root == NIL) return ;        int key = Find_rank(X);        Node *x = Find_kth(key-1);        splay(x, NIL);        key = Find_rank(X);        Node *y = Find_kth(key+1);        splay(y, root);        Node *target = root->ch[1]->ch[0];        if(target->cnt > 1) {            target->cnt--;            target->sz--;            splay(target, NIL);            return ;        }        target->fa->ch[0] = NIL;        root->ch[1]->Update();        splay(root->ch[1], NIL);    }    void Flip(Node *target) { target->flag ^= 1; }    void Build(Node * &target, int l, int r, Node *F)    {        if(r < l) return ;        target = NewNode();        int mid = (l + r) >> 1;        target->Min = target->key = A[mid];        target->fa = F;        Build(target->ch[0], l, mid-1, target);        Build(target->ch[1], mid+1, r, target);        target->Update();    }    Node *Find_kth(int k) { return Find_kth(root, k); }    int Find_rank(int k) { return Find_rank(root, k); }    void Print(Node *target)    {        if(target == NIL) return ;        Print(target->ch[0]);        printf("%d ", target->key);        Print(target->ch[1]);    }};Splay_Tree sp;int main(){    scanf("%d", &n);    for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); T[i] = a[i]; }    sort(T+1, T+1+n);    for(int i = 1; i <= n; i++) {        A[i+1] = lower_bound(T+1, T+1+n, a[i]) - T;        A[i+1] += app[A[i+1]]++;    }    A[1] = INF; A[n+2] = INF;    sp.Build(sp.root, 1, n+2, NIL);    for(int i = 1; i <= n; i++)    {        int R = sp.Find_rank(i);        sp.splay(sp.Find_kth(1), NIL);        sp.splay(sp.Find_kth(R+1), sp.root);        sp.Flip(sp.root->ch[1]->ch[0]);        if(i!=n) printf("%d ", R-1+i-1);        else printf("%d", R-1+i-1);        sp.Del(i);    }}


0 0
原创粉丝点击