zoukankan      html  css  js  c++  java
  • 1269: [AHOI2006]文本编辑器editor

    1269: [AHOI2006]文本编辑器editor

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 4718  Solved: 1807
    [Submit][Status][Discuss]

    Description

    这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器。你能帮助他吗?为了明确任务目标,可可对“文本编辑器”做了一个抽象的定义:   文本:由0个或多个字符构成的序列。这些字符的ASCII码在闭区间[32, 126]内,也就是说,这些字符均为可见字符或空格。光标:在一段文本中用于指示位置的标记,可以位于文本的第一个字符之前,文本的最后一个字符之后或文本的某两个相邻字符之间。文本编辑器:为一个可以对一段文本和该文本中的一个光标进行如下七条操作的程序。如果这段文本为空,我们就说这个文本编辑器是空的。 编写一个程序: 建立一个空的文本编辑器。 从输入文件中读入一些操作指令并执行。 对所有执行过的GET操作,将指定的内容写入输出文件。

    Input

    输入文件中第一行是指令条数N,以下是需要执行的N个操作。除了回车符之外,输入文件的所有字符的ASCII码都在闭区间[32, 126]内。且行尾没有空格。

    Output

    依次对应输入文件中每条GET指令的输出,不得有任何多余的字符。

    Sample Input

    10
    Insert 13
    Balanced eert
    Move 2
    Delete 5
    Next
    Insert 7
    editor
    Move 0
    Get
    Move 11
    Rotate 4
    Get

    Sample Output

    B
    t

    HINT

    对输入数据我们有如下假定: MOVE操作不超过50 000个,INSERT、DELETE和ROTATE操作作的总个数不超过6 000,GET操作不超过20 000个,PREV和NEXT操作的总个数不超过20 000。 所有INSERT插入的字符数之和不超过2M(1M=1 024*1 024)。 DELETE操作、ROTATE操作和GET操作执行时光标后必然有足够的字符。MOVE、PREV、NEXT操作不会把光标移动到非法位置。 输入文件没有错误。

    Source

    分析

    纪念:我的第一颗splay树!!!

    写的有点丑,splay恰好都支持这些功能,所以用的是splay。。

    code

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<cmath>
      6 #include<map>
      7 #include<queue>
      8 
      9 using namespace std;
     10 
     11 const int N = 2000100;
     12 
     13 int ch[N][2],fa[N],data[N],tag[N],siz[N];
     14 int t[100100],st[100100],top;
     15 int tn,Root;
     16 
     17 inline int read() {
     18     int x = 0,f = 1;char ch = getchar();
     19     for (; ch<'0'||ch>'9'; ch = getchar()) 
     20         if (ch=='-') f = -1;
     21     for (; ch>='0'&&ch<='9'; ch = getchar()) 
     22         x = x*10+ch-'0';
     23     return x * f;
     24 }
     25 inline int son(int x) {
     26     return x==ch[fa[x]][1];
     27 }
     28 inline void pushup(int x) {
     29     siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1;
     30 }
     31 inline void pushdown(int x) {
     32     if (tag[x]) {
     33         tag[ch[x][0]] ^= 1;tag[ch[x][1]] ^= 1;
     34         swap(ch[x][0],ch[x][1]);
     35         tag[x] ^= 1;
     36     }
     37 }
     38 inline void rotate(int x) {
     39     int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b];
     40     if (z) ch[z][c] = x;else Root = x;fa[x] = z; 
     41     ch[x][!b] = y;fa[y] = x; 
     42     ch[y][b] = a;if (a) fa[a] = y; 
     43     pushup(y);pushup(x);
     44 }
     45 inline void splay(int x,int rt) {
     46    /* top = 0;int p = x; 
     47     while (p) st[++top] = p,p = fa[p];
     48     while (top) pushdown(st[top]),top--;*/ // 这个地方在查找是已经下传了 
     49     while (fa[x] != rt) {
     50         int y = fa[x],z = fa[y];
     51         if (z==rt) rotate(x);
     52         else {
     53             if (son(x)==son(y)) rotate(y),rotate(x);
     54             else rotate(x),rotate(x);
     55         }
     56     }
     57 }
     58 inline int getkth(int k) {
     59     int p = Root;
     60     while (true) {
     61         pushdown(p);
     62         if (k==siz[ch[p][0]] + 1) return p;
     63         if (ch[p][0] && k <= siz[ch[p][0]]) p = ch[p][0];
     64         else {
     65             k -= ((ch[p][0] ? siz[ch[p][0]] : 0) + 1);
     66             p = ch[p][1];
     67         }
     68     }
     69 }
     70 int build(int l,int r) {
     71     if (l > r) return 0;
     72     int mid = (l + r) >> 1;
     73     int tmp = build(l,mid-1);
     74     fa[tmp] = mid;ch[mid][0] = tmp;
     75     tmp = build(mid+1,r);
     76     fa[tmp] = mid;ch[mid][1] = tmp;
     77     pushup(mid);
     78     return mid;
     79 }
     80 inline void Insert(int p) {
     81     int x = read();
     82     char c;
     83     for (int i=1; i<=x; ++i) {c = getchar();data[++tn] = (int)c;}
     84     int tmp = build(tn-x+1,tn);
     85     int L = getkth(p),R = getkth(p + 1);
     86     splay(L,0);splay(R,L);
     87     fa[tmp] = R;ch[R][0] = tmp;
     88     pushup(R);pushup(L);
     89 }
     90 inline void Delete(int p,int x) {
     91     int L = getkth(p),R = getkth(p+x+1);
     92     splay(L,0);splay(R,L);
     93     ch[R][0] = 0;fa[ch[R][0]] = 0;
     94     pushup(R);pushup(L);
     95 }
     96 inline void rever(int l,int x) {
     97     int r = l + x + 1;
     98     int L = getkth(l),R = getkth(r);
     99     splay(L,0);splay(R,L);
    100     tag[ch[R][0]] ^= 1;
    101 }
    102 int main() {
    103     
    104     int n = read(),now = 1,x;
    105     char s[20];
    106     Root = 1;ch[1][1] = 2;fa[2] = 1;siz[1] = 2;siz[2] = 1;tn = 2;
    107     while (n--) {
    108         scanf("%s",s);
    109         if (s[0]=='I') Insert(now);
    110         else if (s[0]=='D') Delete(now,read());
    111         else if (s[0]=='M') {
    112             x = read();now = x + 1;
    113         }
    114         else if (s[0]=='R') rever(now,read());
    115         else if (s[0]=='G') {
    116             x = getkth(now + 1);printf("%c
    ",data[x]);
    117         }
    118         else if (s[0]=='P') now --;
    119         else if (s[0]=='N') now ++;
    120     }
    121     return 0;
    122 }
  • 相关阅读:
    js 使用${}解析变量代替++
    laravel 返回自定义错误
    Java集合之HashMap源码解析
    Java集合之ArrayList源码解析
    Java集合之LinkedList源码解析
    保证消息可靠性传输以及幂等性
    Java分布式系统---消息中间件
    Java中的日期与时间
    Java时区问题
    数据测试002:利用Jmeter推送测试数据(上)
  • 原文地址:https://www.cnblogs.com/mjtcn/p/8046028.html
Copyright © 2011-2022 走看看