zoukankan      html  css  js  c++  java
  • [BZOJ1507] [NOI2003] Editor (splay)

    Description

    Input

      输入文件editor.in的第一行是指令条数t,以下是需要执行的t个操作。其中: 为了使输入文件便于阅读,Insert操作的字符串中可能会插入一些回车符,请忽略掉它们(如果难以理解这句话,可以参考样例)。 除了回车符之外,输入文件的所有字符的ASCII码都在闭区间[32, 126]内。且行尾没有空格。
      这里我们有如下假定:
       MOVE操作不超过50000个,INSERT和DELETE操作的总个数不超过4000,PREV和NEXT操作的总个数不超过200000。
       所有INSERT插入的字符数之和不超过2M(1M=1024*1024),正确的输出文件长度不超过3M字节。
       DELETE操作和GET操作执行时光标后必然有足够的字符。MOVE、PREV、NEXT操作必然不会试图把光标移动到非法位置。
       输入文件没有错误。 对C++选手的提示:经测试,最大的测试数据使用fstream进行输入有可能会比使用stdio慢约1秒。

    Output

      输出文件editor.out的每行依次对应输入文件中每条GET指令的输出。

    Sample Input

    15
    Insert 26
    abcdefghijklmnop
    qrstuv wxy
    Move 15
    Delete 11
    Move 5
    Insert 1
    ^
    Next
    Insert 1
    _
    Next
    Next
    Insert 4
    ./.
    Get 4
    Prev
    Insert 1
    ^
    Move 0
    Get 22

    Sample Output

    ./.
    abcde^_^f./.ghijklmno

    HINT 

    Source

    Solution

      splay的区间操作。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 struct spaly
      4 {
      5     char key;
      6     int siz, fa, c[2];
      7 }a[2100005];
      8 char inss[2100005];
      9 int ptot;
     10  
     11 void push_up(int k)
     12 {
     13     a[k].siz = a[a[k].c[0]].siz + a[a[k].c[1]].siz + 1;
     14 }
     15  
     16 void rotate(int &k, int x)
     17 {
     18     int y = a[x].fa, z = a[y].fa;
     19     int dy = a[y].c[1] == x, dz = a[z].c[1] == y;
     20     if(k == y) k = x, a[x].fa = z;
     21     else a[z].c[dz] = x, a[x].fa = z;
     22     a[y].c[dy] = a[x].c[!dy], a[a[x].c[!dy]].fa = y;
     23     a[x].c[!dy] = y, a[y].fa = x;
     24     push_up(y);
     25 }
     26  
     27 void splay(int &k, int x)
     28 {
     29     while(k != x)
     30     {
     31         int y = a[x].fa, z = a[y].fa;
     32         if(k != y)
     33             if(a[y].c[1] == x ^ a[z].c[1] == y) rotate(k, x);
     34             else rotate(k, y);
     35         rotate(k, x);
     36     }
     37     push_up(x);
     38 }
     39  
     40 int find(int k, int x)
     41 {
     42     if(!k || x == a[a[k].c[0]].siz + 1) return k;
     43     if(x <= a[a[k].c[0]].siz) return find(a[k].c[0], x);
     44     return find(a[k].c[1], x - a[a[k].c[0]].siz - 1);
     45 }
     46  
     47 void build(int &k, int fa, int i, int m)
     48 {
     49     if(i == m) return;
     50     k = ++ptot, a[k].fa = fa, a[k].key = inss[i];
     51     build(a[k].c[1], k, i + 1, m);
     52     push_up(k);
     53 }
     54  
     55 void printf(int k)
     56 {
     57     if(!k) return;
     58     printf(a[k].c[0]), printf("%c", a[k].key), printf(a[k].c[1]);
     59 }
     60  
     61 int main()
     62 {
     63     int n, m, root = 1, pos = 0, ctot = 0;
     64     char op[10];
     65     scanf("%d", &n), ptot = 2;
     66     a[1].c[1] = 2, a[1].siz = 2, a[2].siz = 1, a[2].fa = 1;
     67     while(n--)
     68     {
     69         scanf("%s", op);
     70         if(op[0] == 'M') scanf("%d", &pos);
     71         if(op[0] == 'I')
     72         {
     73             scanf("%d", &m), ctot += m;
     74             for(int i = 0; i < m; i++)
     75             {
     76                 inss[i] = getchar();
     77                 if(inss[i] < 32 || inss[i] > 126) i--;
     78             }
     79             splay(root, find(root, pos + 1));
     80             splay(a[root].c[1], find(root, pos + 2));
     81             build(a[a[root].c[1]].c[0], a[root].c[1], 0, m);
     82             push_up(a[root].c[1]), push_up(root);
     83         }
     84         if(op[0] == 'D')
     85         {
     86             scanf("%d", &m), m = min(m, ctot - pos);
     87             splay(root, find(root, pos + 1));
     88             splay(a[root].c[1], find(root, pos + m + 2));
     89             a[a[root].c[1]].c[0] = 0, ctot -= m;
     90             push_up(a[root].c[1]), push_up(root);
     91         }
     92         if(op[0] == 'G')
     93         {
     94             scanf("%d", &m), m = min(m, ctot - pos);
     95             splay(root, find(root, pos + 1));
     96             splay(a[root].c[1], find(root, pos + m + 2));
     97             printf(a[a[root].c[1]].c[0]), puts("");
     98         }
     99         if(op[0] == 'P') pos--;
    100         if(op[0] == 'N') pos++;
    101     }
    102     return 0;
    103 }
    View Code
  • 相关阅读:
    域渗透:ptk(pass the key)
    QQ拼音输入法6.0 DLL劫持实现提权
    进程关系
    进程控制
    进程环境
    系统数据文件和信息
    文件和目录
    标准I/O
    文件描述符标志/文件表项
    SSL安全原理
  • 原文地址:https://www.cnblogs.com/CtrlCV/p/5356594.html
Copyright © 2011-2022 走看看