zoukankan      html  css  js  c++  java
  • HDU 3487 Play with Chain (splay tree)

    Play with Chain

    Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 2783    Accepted Submission(s): 1141


    Problem Description
    YaoYao is fond of playing his chains. He has a chain containing n diamonds on it. Diamonds are numbered from 1 to n.
    At first, the diamonds on the chain is a sequence: 1, 2, 3, …, n.
    He will perform two types of operations:
    CUT a b c: He will first cut down the chain from the ath diamond to the bth diamond. And then insert it after the cth diamond on the remaining chain.
    For example, if n=8, the chain is: 1 2 3 4 5 6 7 8; We perform “CUT 3 5 4”, Then we first cut down 3 4 5, and the remaining chain would be: 1 2 6 7 8. Then we insert “3 4 5” into the chain before 5th diamond, the chain turns out to be: 1 2 6 7 3 4 5 8.

    FLIP a b: We first cut down the chain from the ath diamond to the bth diamond. Then reverse the chain and put them back to the original position.
    For example, if we perform “FLIP 2 6” on the chain: 1 2 6 7 3 4 5 8. The chain will turn out to be: 1 4 3 7 6 2 5 8

    He wants to know what the chain looks like after perform m operations. Could you help him? 
     
    Input
    There will be multiple test cases in a test data. 
    For each test case, the first line contains two numbers: n and m (1≤n, m≤3*100000), indicating the total number of diamonds on the chain and the number of operations respectively.
    Then m lines follow, each line contains one operation. The command is like this:
    CUT a b c // Means a CUT operation, 1 ≤ a ≤ b ≤ n, 0≤ c ≤ n-(b-a+1).
    FLIP a b    // Means a FLIP operation, 1 ≤ a < b ≤ n.
    The input ends up with two negative numbers, which should not be processed as a case.
     
    Output
    For each test case, you should print a line with n numbers. The ith number is the number of the ith diamond on the chain.
     
    Sample Input
    8 2 CUT 3 5 4 FLIP 2 6 -1 -1
     
    Sample Output
    1 4 3 7 6 2 5 8
     
    Source
     
    Recommend
    zhengfeng
      1 /* ***********************************************
      2 Author        :kuangbin
      3 Created Time  :2013/8/25 23:35:30
      4 File Name     :F:2013ACM练习专题学习splay_tree_2HDU3487.cpp
      5 ************************************************ */
      6 
      7 #include <stdio.h>
      8 #include <string.h>
      9 #include <iostream>
     10 #include <algorithm>
     11 #include <vector>
     12 #include <queue>
     13 #include <set>
     14 #include <map>
     15 #include <string>
     16 #include <math.h>
     17 #include <stdlib.h>
     18 #include <time.h>
     19 using namespace std;
     20 
     21 #define Key_value ch[ch[root][1]][0]
     22 const int MAXN = 300010;
     23 int pre[MAXN],ch[MAXN][2],root,tot1;
     24 int key[MAXN],rev[MAXN];
     25 int size[MAXN];
     26 int s[MAXN],tot2;
     27 int n,q;
     28 
     29 void NewNode(int &r,int father,int k)
     30 {
     31     if(tot2) r = s[tot2--];
     32     else r = ++tot1;
     33     key[r] = k;
     34     pre[r] = father;
     35     rev[r] = 0;
     36     ch[r][0] = ch[r][1] = 0;
     37     size[r] = 1;
     38 }
     39 //反转的更新
     40 void Update_Rev(int r)
     41 {
     42     if(!r) return;
     43     swap(ch[r][0],ch[r][1]);
     44     rev[r] ^= 1;
     45 }
     46 void push_up(int r)
     47 {
     48     size[r] = size[ch[r][0]] + size[ch[r][1]] + 1;
     49 }
     50 void push_down(int r)
     51 {
     52     if(rev[r])
     53     {
     54         Update_Rev(ch[r][0]);
     55         Update_Rev(ch[r][1]);
     56         rev[r] = 0;
     57     }
     58 }
     59 
     60 void Build(int &x,int l,int r,int father)
     61 {
     62     if(l > r)return;
     63     int mid = (l+r)/2;
     64     NewNode(x,father,mid);
     65     Build(ch[x][0],l,mid-1,x);
     66     Build(ch[x][1],mid+1,r,x);
     67     push_up(x);
     68 }
     69 void Init()
     70 {
     71     root = tot1 = tot2 = 0;
     72     ch[root][0] = ch[root][1] = size[root] = key[root] = pre[root] = rev[root] = 0;
     73     NewNode(root,0,-1);
     74     NewNode(ch[root][1],root,-1);
     75     Build(Key_value,1,n,ch[root][1]);
     76     push_up(ch[root][1]);
     77     push_up(root);
     78 }
     79 void Rotate(int x,int kind)
     80 {
     81     int y = pre[x];
     82     push_down(y);
     83     push_down(x);
     84     ch[y][!kind] = ch[x][kind];
     85     pre[ch[x][kind]] = y;
     86     if(pre[y])
     87         ch[pre[y]][ch[pre[y]][1]==y] = x;
     88     pre[x] = pre[y];
     89     ch[x][kind] = y;
     90     pre[y] = x;
     91     push_up(y);
     92 }
     93 void Splay(int r,int goal)
     94 {
     95     push_down(r);
     96     while(pre[r] != goal)
     97     {
     98         if(pre[pre[r]] == goal)
     99         {
    100             push_down(pre[r]);
    101             push_down(r);
    102             Rotate(r,ch[pre[r]][0]==r);
    103         }
    104         else
    105         {
    106             push_down(pre[pre[r]]);
    107             push_down(pre[r]);
    108             push_down(r);
    109             int y = pre[r];
    110             int kind = ch[pre[y]][0]==y;
    111             if(ch[y][kind] == r)
    112             {
    113                 Rotate(r,!kind);
    114                 Rotate(r,kind);
    115             }
    116             else
    117             {
    118                 Rotate(y,kind);
    119                 Rotate(r,kind);
    120             }
    121         }
    122     }
    123     push_up(r);
    124     if(goal == 0)root = r;
    125 }
    126 int Get_kth(int r,int k)
    127 {
    128     push_down(r);
    129     int t = size[ch[r][0]] + 1;
    130     if(t == k)return r;
    131     if(t > k)return Get_kth(ch[r][0],k);
    132     else return Get_kth(ch[r][1],k-t);
    133 }
    134 //将[l,r]段剪切下来,放在剩下段的第c个后面
    135 void CUT(int l,int r,int c)
    136 {
    137     Splay(Get_kth(root,l),0);
    138     Splay(Get_kth(root,r+2),root);
    139     int tmp = Key_value;
    140     Key_value = 0;
    141     push_up(ch[root][1]);
    142     push_up(root);
    143     Splay(Get_kth(root,c+1),0);
    144     Splay(Get_kth(root,c+2),root);
    145     Key_value = tmp;
    146     pre[Key_value] = ch[root][1];
    147     push_up(ch[root][1]);
    148     push_up(root);
    149 }
    150 //将[l,r]段反转
    151 void FLIP(int l,int r)
    152 {
    153     Splay(Get_kth(root,l),0);
    154     Splay(Get_kth(root,r+2),root);
    155     Update_Rev(Key_value);
    156     push_up(ch[root][1]);
    157     push_up(root);
    158 }
    159 //按顺序输出
    160 int cnt;
    161 void InOrder(int r)
    162 {
    163     if(!r)return;
    164     push_down(r);
    165     InOrder(ch[r][0]);
    166     if(cnt >=1 && cnt <= n)
    167     {
    168         printf("%d",key[r]);
    169         if(cnt < n)printf(" ");
    170         else printf("
    ");
    171     }
    172     cnt++;
    173     InOrder(ch[r][1]);
    174 }
    175 int main()
    176 {
    177     //freopen("in.txt","r",stdin);
    178     //freopen("out.txt","w",stdout);
    179     while(scanf("%d%d",&n,&q) == 2)
    180     {
    181         if( n < 0 && q < 0)break;
    182         Init();
    183         char op[20];
    184         int x,y,z;
    185         while(q--)
    186         {
    187             scanf("%s",op);
    188             if(op[0] == 'C')
    189             {
    190                 scanf("%d%d%d",&x,&y,&z);
    191                 CUT(x,y,z);
    192             }
    193             else
    194             {
    195                 scanf("%d%d",&x,&y);
    196                 FLIP(x,y);
    197             }
    198         }
    199         cnt = 0;
    200         InOrder(root);
    201     }
    202     return 0;
    203 }
  • 相关阅读:
    如何在HTML5 图片预览
    js本地图片预览代码兼容所有浏览器
    c#无损高质量压缩图片
    c#如何在win7下设置IE代理的完美解决方案
    关于Android 访问权限设置
    在asp.net mvc中将checkbox传到后台时总是true的解决方法
    IO流
    Map集合重要练习
    Map笔记总结
    泛型笔记
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3283802.html
Copyright © 2011-2022 走看看