UVA 11922 Permutation Transformer —— splay伸展樹

來源:互聯網
上載者:User

標籤:flip   else   seq   --   log   表示   粘貼   orm   main   

題意:根據m條指令改變排列1 2 3 4 … n ,每條指令(a, b)表示取出第a~b個元素,反轉後添加到排列尾部

分析:用一個可分裂合并的序列來表示整個序列,截取一段可以用兩次分裂一次合并實現,粘貼到末尾可以用一次合并實現。

翻轉可以採用在每個結點上做標記的方法,flip = 1意味著將這棵子樹翻轉,可以類似線段樹用一個pushdown()實現標記向下傳遞。

可以發現當前排列就是伸展樹的中序遍曆序列。中序遍曆列印結果即可。

注意代碼中設定了虛擬首結點0的技巧。

代碼如下:

  1 #include <cstdio>  2 #include <cstdlib>  3 #include <iostream>  4 #include <vector>  5 using namespace std;  6   7 struct Node {  8     Node* ch[2];  9     int r, v, s; 10     int flip; 11     Node(int vv): v(vv) { 12         r = rand(); 13         s = 1;  14         ch[0] = ch[1] = NULL; 15         flip = 0; 16     } 17     bool cmp(const int &x) const { 18         if(x == v) return -1; 19         return x < v ? 0 : 1; 20     } 21     void maintain() { 22         s = 1;  23         if(ch[0] != NULL) s += ch[0]->s; 24         if(ch[1] != NULL) s += ch[1]->s; 25     } 26     void pushdown() { 27         if(flip) { 28             flip = 0; 29             swap(ch[0], ch[1]); 30             if(ch[0] != NULL) ch[0]->flip = !ch[0]->flip; 31             if(ch[1] != NULL) ch[1]->flip = !ch[1]->flip; 32         } 33     } 34 }; 35 void rotate(Node* &o, int d) { 36     Node* k = o->ch[d^1]; o->ch[d^1] = k->ch[d]; k->ch[d] = o; 37     o->maintain(); k->maintain(); o = k; 38 } 39 void insert(Node* &o, int x) { 40     if(o == NULL) o = new Node(x); 41     else { 42         int d = o->cmp(x); 43         insert(o->ch[d], x); 44         if(o->ch[d]->r > o->r) rotate(o, d^1); 45     } 46     o->maintain(); 47 } 48  49 void splay(Node* &o, int k) { 50     o->pushdown(); 51     int s = o->ch[0] == NULL ? 0 : o->ch[0]->s; 52     int d = k <= s ? 0 : (k == s+1 ? -1 : 1); 53     if(d == 1) k -= s+1; 54     if(d != -1) { 55         splay(o->ch[d], k); 56         rotate(o, d^1); 57     } 58 } 59  60 Node* merge(Node* left, Node* right) { 61     splay(left, left->s); 62     left->ch[1] = right; 63     left->maintain(); 64     return left; 65 } 66  67 void split(Node* o, int k , Node* &left, Node* &right) { 68     splay(o, k); 69     left = o; 70     right = o->ch[1]; 71     o->ch[1] = NULL; 72     left->maintain(); 73 } 74 vector<int> seq; 75 void dfs(Node* o) { 76     if(o == NULL) return; 77     o->pushdown(); 78     dfs(o->ch[0]); 79     if(o->v) { 80         //printf("%d ", o->v); 81         seq.push_back(o->v); 82     } 83     dfs(o->ch[1]); 84 } 85 int n, m; 86 int main() { 87     cin >> n >> m; 88     Node* root = new Node(0); //虛擬首結點0,方便分裂操作 89     for(int i = 1; i <= n; i++) insert(root, i); 90     while(m--) { 91         int a, b; 92         cin >> a >> b; 93         Node *left, *mid, *right, *o; 94         split(root, a, left, o); 95         split(o, b-a+1, mid, right); 96         mid->flip ^= 1; 97         root = merge(merge(left, right), mid); 98     } 99     dfs(root);100     for(int i = 0; i < seq.size(); i++) cout<<seq[i]<<endl;101     return 0;102 }

 

UVA 11922 Permutation Transformer —— splay伸展樹

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.