【POJ2887】【块状链表】Big String

Description

You are given a string and supposed to do some string manipulations.

Input

The first line of the input contains the initial string. You can assume that it is non-empty and its length does not exceed 1,000,000.

The second line contains the number of manipulation commands N (0 < N ≤ 2,000). The following N lines describe a command each. The commands are in one of the two formats below:

  1. I ch p: Insert a character ch before the p-th character of the current string. If p is larger than the length of the string, the character is appended to the end of the string.
  2. Q p: Query the p-th character of the current string. The input ensures that the p-th character exists.

All characters in the input are digits or lowercase letters of the English alphabet.

Output

For each Q command output one line containing only the single character queried.

Sample Input

ab

7

Q 1

I c 2

I d 4

I e 2

Q 5

I f 1

Q 3

Sample Output

a

d

e

Source

【分析】

知识拿块状链表练练手而已。

这是我写的第一个块状链表,怎么说呢,块状链表应该说是写起来比较麻烦的,因为要注意的边界条件有点多,不过适应了应该会很好骗分。

  1 #include <iostream>

  2 #include <cstdio>

  3 #include <algorithm>

  4 #include <cstring>

  5 #include <vector>

  6 #include <utility>

  7 #include <iomanip>

  8 #include <string>

  9 #include <cmath>

 10 #include <queue>

 11 #include <map>

 12 

 13 const int MAXC = 1000000 + 10; 

 14 const int MAXM = 1000 + 10; 

 15 const int MAXN = 1000000 + 10;

 16 const int N=2000, L=2000;//L代表单个块的长度,N为最大的总块数 

 17 using namespace std;

 18 struct Block_List {//BLOCK_LIST为块状链表的英文名 

 19     struct Node {

 20         char str[L];

 21         //next数组志向下一个块状链表 

 22         int next, size;

 23         void init(){

 24              memset(str, 0, sizeof(str));

 25              next = -1;

 26              size = 0;

 27         }

 28     }list[N];

 29     int head, tot;

 30 

 31     void init(char str[]){

 32          head = tot = 0;//整个块状链表进行初始化

 33          list[tot++].init();//进行第一个块状链表的初始化

 34          for (int i = 0, cur = head; str[i]; cur = list[cur].next){

 35              for (int j = 0; j < L && str[i]; j++, i++){

 36                  list[cur].str[j] = str[i];

 37                  list[cur].size++;

 38              }

 39              //还能继续装 

 40              if (str[i]){

 41                 list[tot].init();//注意tot永远指向下一个空的块状链表

 42                 list[cur].next = tot++; 

 43              }

 44          } 

 45          for (int cur = head; cur != -1; cur = list[cur].next)

 46          if (list[cur].size == L) split(cur);//分割块状链表 

 47     }

 48     //对第x块块状链表进行分割 

 49     void split(int x){

 50          list[tot].init();

 51          //注意块状链表的下标是从0 - (L - 1) 

 52          for (int i = L / 2; i < L; i++){

 53              list[tot].str[i - L/2] = list[x].str[i];

 54              list[tot].size++;

 55              list[x].size--;

 56              list[x].str[i] = 0;//清空?好像没什么用 

 57          }

 58          list[tot].next = list[x].next;

 59          list[x].next = tot++;

 60     }

 61     void insert(int pos, char val){

 62          int cur = head;

 63          //注意开始不需要-1是因为一定成立,注意不要让任何一个块状链表达到满的状态,不然维护起来很麻烦 

 64          while (pos - list[cur].size > 0 && list[cur].next != -1){

 65                pos -= list[cur].size;

 66                cur = list[cur].next; 

 67          }

 68          if (pos >= list[cur].size) list[cur].str[list[cur].size] = val;

 69          else {

 70               //先进行移动

 71               for (int i = list[cur].size; i > pos; i--) list[cur].str[i] = list[cur].str[i - 1] ;

 72               list[cur].str[pos] = val;

 73          }

 74          list[cur].size++;

 75          if (list[cur].size == L) split(cur);

 76     }

 77     char find(int pos){

 78          int cur = head;

 79          while ( pos - list[cur].size > 0){

 80                pos -= list[cur].size;

 81                cur = list[cur].next;

 82          }

 83          return list[cur].str[pos - 1];//注意要-1 

 84     }

 85 }A;

 86 char str[MAXN];

 87 int n;

 88 

 89 int main() {

 90     #ifdef LOCAL

 91     freopen("data.txt",  "r",  stdin);

 92     freopen("out.txt",  "w",  stdout); 

 93     #endif

 94     scanf("%s%d", str, &n);

 95     A.init(str);//初始化块状链表

 96     for (int i = 0; i < n; i++){

 97         int pos;

 98         scanf("%s", str);

 99         if (str[0] == 'I'){//插入单个的单词 

100            char S[2]; 

101            scanf("%s%d", S, &pos);

102            A.insert(pos - 1, S[0]);

103         } else {

104            scanf("%d", &pos);

105            printf("%c\n", A.find( pos ));

106         }

107     } 

108     return 0;

109 }
View Code

 

你可能感兴趣的:(String)