程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> BZOJ 3506 CQOI 2014 排序機械臂 Splay

BZOJ 3506 CQOI 2014 排序機械臂 Splay

編輯:C++入門知識

BZOJ 3506 CQOI 2014 排序機械臂 Splay


題目大意:給出一個序列,給出一種排序方式,模擬這種排序方式排序,並輸出每次找到的節點的位置。


思路:它讓你做什麼你就做什麼,無非就是個Reverse,很簡單。注意一下排序的時候權值相等的情況就行了。


CODE:

#include 
#include 
#include 
#include 
#define MAX 100010
#define INF 0x3f3f3f3f
using namespace std;
 
struct SplayTree{
    SplayTree *son[2],*father;
    bool reverse;
    int size;
     
    SplayTree();
    bool Check() {
        return father->son[1] == this;
    }
    void Combine(SplayTree *a,bool dir) {
        a->father = this;
        son[dir] = a;
    }
    void Reverse() {
        reverse ^= 1;
        swap(son[0],son[1]);
    }
    void PushUp() {
        size = son[0]->size + son[1]->size + 1;
    }
    void PushDown() {
        if(reverse) {
            son[0]->Reverse();
            son[1]->Reverse();
            reverse = false;
        }
    }
}none,*nil = &none,*root;
SplayTree:: SplayTree() {
    son[0] = son[1] = nil;
    reverse = false;
    size = 1;
}
 
struct Complex{
    int val,pos;
    SplayTree *a;
     
    bool operator <(const Complex &a)const {
        if(val == a.val)    return pos < a.pos;
        return val < a.val;
    }
    void Read(int p) {
        scanf("%d",&val);
        pos = p;
    }
}src[MAX];
 
int cnt;
 
void Pretreatment()
{
    nil->size = 0;
    nil->son[0] = nil->son[1] = nil->father = nil;
}
 
SplayTree *BuildTree(int l,int r)
{
    if(l > r)    return nil;
    int mid = (l + r) >> 1;
    SplayTree *re = new SplayTree();
    src[mid].a = re;
    re->Combine(BuildTree(l,mid - 1),false);
    re->Combine(BuildTree(mid + 1,r),true);
    re->PushUp();
    return re;  
}
 
inline void Rotate(SplayTree *a,bool dir)
{
    SplayTree *f = a->father;
    f->PushDown(); a->PushDown();
    f->son[!dir] = a->son[dir];
    f->son[!dir]->father = f;
    a->son[dir] = f;
    a->father = f->father;
    f->father->son[f->Check()] = a;
    f->father = a;
    f->PushUp();
    if(f == root)   root = a;
}
 
inline void Splay(SplayTree *a,SplayTree *aim)
{
    while(a->father != aim) {
        if(a->father->father == aim)
            Rotate(a,!a->Check());
        else if(!a->father->Check()) {
            if(!a->Check())
                Rotate(a->father,true),Rotate(a,true);
            else    Rotate(a,false),Rotate(a,true);
        }
        else {
            if(a->Check())
                Rotate(a->father,false),Rotate(a,false);
            else    Rotate(a,true),Rotate(a,false);
        }
    }
    a->PushUp();
}
 
SplayTree *Find(SplayTree *a,int k)
{
    a->PushDown();
    if(a->son[0]->size >= k)   return Find(a->son[0],k);
    k -= a->son[0]->size;
    if(k == 1)  return a;
    return Find(a->son[1],k - 1);
}
 
inline void SplaySeg(int x,int y)
{
    x++,y++;
    Splay(Find(root,x - 1),nil);
    Splay(Find(root,y + 1),root);
}
 
int main()
{
    cin >> cnt;
    Pretreatment();
    for(int i = 1; i <= cnt; ++i)
        src[i].Read(i); 
    src[0].val = src[cnt + 1].val = INF;
    root = BuildTree(0,cnt + 1);
    root->father = nil;
    sort(src + 1,src + cnt + 1);
    for(int i = 1; i <= cnt; ++i) {
        Splay(src[i].a,nil);
        printf("%d%c",root->son[0]->size," \n"[i == cnt]);
        SplaySeg(i,root->son[0]->size);
        root->son[1]->son[0]->Reverse();
    }
    return 0;
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved