zoukankan      html  css  js  c++  java
  • 1507: [NOI2003]Editor(块状链表)

    1507: [NOI2003]Editor

    Time Limit: 5 Sec  Memory Limit: 162 MB
    Submit: 4157  Solved: 1677
    [Submit][Status][Discuss]

    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

    code

      1 #include<cstdio>
      2 #include<cstring>
      3 
      4 const int MAXL = 2100000; 
      5 const int Block_size = 5010; 
      6 const int Block_num = 600; 
      7 int Number[Block_num],Tot;
      8 int nxt[Block_num],siz[Block_num]; 
      9 char data[Block_num][Block_size]; 
     10 char str[MAXL],s[20];
     11 
     12 void Init() {
     13     for (int i=1; i<Block_num; ++i) 
     14         Number[i] = i;
     15     Tot = 1;
     16     nxt[0] = -1;siz[0] = 0; 
     17 }
     18 int Getnum() {
     19     return Number[Tot++];
     20 } 
     21 void Delnum(int x) {
     22     Number[--Tot] = x;
     23 }
     24 int find(int &pos) {
     25     int k = 0;
     26     while (k != -1 && pos > siz[k]) {
     27         pos -= siz[k];
     28         k = nxt[k];
     29     }
     30     return k;
     31 }
     32 void Madenews(int cur,int news,int num,char str[]) {
     33     if (news!=-1) {
     34         nxt[news] = nxt[cur];
     35         siz[news] = num;
     36         memcpy(data[news],str,num);
     37     }
     38     nxt[cur] = news;
     39 } 
     40 void split(int cur,int pos) {
     41     if (cur==-1 || pos==siz[cur]) return ;
     42     int news = Getnum();
     43     Madenews(cur,news,siz[cur]-pos,data[cur]+pos);
     44     siz[cur] = pos;
     45 } 
     46 void Merge(int x,int y) {
     47     memcpy(data[x]+siz[x],data[y],siz[y]);
     48     siz[x] += siz[y];
     49     nxt[x] = nxt[y];
     50     Delnum(y);
     51 } 
     52 void Maintain() {
     53     int cur = 0; 
     54     while (cur != -1) { 
     55         int p = nxt[cur];
     56         while (p != -1 && siz[cur] + siz[p] <= Block_size) {
     57             Merge(cur,p);
     58             p = nxt[cur];
     59         }
     60         cur = nxt[cur];
     61     }
     62 }
     63 void Insert(int pos,int num,char str[]) {
     64     int cur = find(pos);
     65     split(cur,pos);
     66     int cnt = 0;
     67     while (cnt + Block_size <= num) {
     68         int news = Getnum();
     69         Madenews(cur,news,Block_size,str+cnt);
     70         cur = news;
     71         cnt += Block_size;
     72     }
     73     if (num - cnt) {
     74         int news = Getnum();
     75         Madenews(cur,news,num-cnt,str+cnt);
     76     } 
     77     Maintain();
     78 }
     79 void Erase(int pos,int num) {
     80     int cur = find(pos);
     81     split(cur,pos);
     82     int p = nxt[cur]; 
     83     while (p != -1 && num > siz[p]) {
     84         num -= siz[p];
     85         p = nxt[p];
     86     }
     87     split(p,num);
     88     p = nxt[p];
     89     for (int i=nxt[cur]; i!=p; i=nxt[cur]) {
     90         nxt[cur] = nxt[i];
     91         Delnum(i);
     92     }
     93     Maintain();
     94 } 
     95 void Getdata(int pos,int num,char str[]) {
     96     int cur = find(pos);
     97     int cnt = siz[cur] - pos;
     98     if (num < cnt) cnt = num;
     99     memcpy(str,data[cur]+pos,cnt);
    100     int tmp = nxt[cur];
    101     while (tmp!=-1 && cnt+siz[tmp] <= num) {
    102         memcpy(str+cnt,data[tmp],siz[tmp]);
    103         cnt += siz[tmp];
    104         tmp = nxt[tmp];
    105     }
    106     if (num - cnt && tmp != -1) 
    107         memcpy(str+cnt,data[tmp],num-cnt);
    108     str[num] = '';
    109 } 
    110 int main() {
    111     Init();
    112     int Nowpos = 0,opt,num;
    113     scanf("%d",&opt);
    114     while (opt) {
    115         opt--;
    116         scanf("%s",s);
    117         if (s[0]=='M') scanf("%d",&Nowpos);
    118         else if (s[0]=='I')    {
    119             scanf("%d",&num);
    120             for (int i=0; i<num; ++i) {
    121                 scanf("%c",&str[i]);
    122                 if (str[i]<32 || str[i]>126) --i;
    123             }
    124             Insert(Nowpos,num,str);    
    125         }
    126         else if (s[0]=='D') {
    127             scanf("%d",&num);
    128             Erase(Nowpos,num);
    129         }
    130         else if (s[0]=='G') {
    131             scanf("%d",&num);
    132             Getdata(Nowpos,num,str);
    133             printf("%s
    ",str);        
    134         }
    135         else if (s[0]=='P') --Nowpos;
    136         else ++Nowpos;
    137     }
    138     return 0;
    139 }
  • 相关阅读:
    CA证书扫盲,https讲解。
    关于jquery的入门,简单的封装。
    anglar JS使用两层ng-repeat嵌套使用,分辨$index
    JS中=>,>>>是什么意思
    撰写html标签的快捷方式2
    CSS 中伪类的顺序
    撰写html标签的快捷方式1
    文字换行显示
    input 控件监听回车确认按钮。
    git常用命令整理
  • 原文地址:https://www.cnblogs.com/mjtcn/p/8097313.html
Copyright © 2011-2022 走看看