【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
", A.find( pos ));
106         }
107     } 
108     return 0;
109 }
View Code
原文地址:https://www.cnblogs.com/hoskey/p/4322417.html