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

【分析】

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

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

 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <utility>
#include <iomanip>
#include <string>
#include <cmath>
#include <queue>
#include <map> const int MAXC = + ;
const int MAXM = + ;
const int MAXN = + ;
const int N=, L=;//L代表单个块的长度,N为最大的总块数
using namespace std;
struct Block_List {//BLOCK_LIST为块状链表的英文名
struct Node {
char str[L];
//next数组志向下一个块状链表
int next, size;
void init(){
memset(str, , sizeof(str));
next = -;
size = ;
}
}list[N];
int head, tot; void init(char str[]){
head = tot = ;//整个块状链表进行初始化
list[tot++].init();//进行第一个块状链表的初始化
for (int i = , cur = head; str[i]; cur = list[cur].next){
for (int j = ; j < L && str[i]; j++, i++){
list[cur].str[j] = str[i];
list[cur].size++;
}
//还能继续装
if (str[i]){
list[tot].init();//注意tot永远指向下一个空的块状链表
list[cur].next = tot++;
}
}
for (int cur = head; cur != -; cur = list[cur].next)
if (list[cur].size == L) split(cur);//分割块状链表
}
//对第x块块状链表进行分割
void split(int x){
list[tot].init();
//注意块状链表的下标是从0 - (L - 1)
for (int i = L / ; i < L; i++){
list[tot].str[i - L/] = list[x].str[i];
list[tot].size++;
list[x].size--;
list[x].str[i] = ;//清空?好像没什么用
}
list[tot].next = list[x].next;
list[x].next = tot++;
}
void insert(int pos, char val){
int cur = head;
//注意开始不需要-1是因为一定成立,注意不要让任何一个块状链表达到满的状态,不然维护起来很麻烦
while (pos - list[cur].size > && list[cur].next != -){
pos -= list[cur].size;
cur = list[cur].next;
}
if (pos >= list[cur].size) list[cur].str[list[cur].size] = val;
else {
//先进行移动
for (int i = list[cur].size; i > pos; i--) list[cur].str[i] = list[cur].str[i - ] ;
list[cur].str[pos] = val;
}
list[cur].size++;
if (list[cur].size == L) split(cur);
}
char find(int pos){
int cur = head;
while ( pos - list[cur].size > ){
pos -= list[cur].size;
cur = list[cur].next;
}
return list[cur].str[pos - ];//注意要-1
}
}A;
char str[MAXN];
int n; int main() {
#ifdef LOCAL
freopen("data.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
scanf("%s%d", str, &n);
A.init(str);//初始化块状链表
for (int i = ; i < n; i++){
int pos;
scanf("%s", str);
if (str[] == 'I'){//插入单个的单词
char S[];
scanf("%s%d", S, &pos);
A.insert(pos - , S[]);
} else {
scanf("%d", &pos);
printf("%c\n", A.find( pos ));
}
}
return ;
}

【POJ2887】【块状链表】Big String的更多相关文章

  1. POJ2887(块状链表)

    Big String Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 6346   Accepted: 1525 Descr ...

  2. POJ 2887 Big String(块状链表)

    题目大意 给一个字符串,长度不超过 106,有两种操作: 1. 在第 i 个字符的前面添加一个字符 ch 2. 查询第 k 个位置是什么字符 操作的总数不超过 2000 做法分析 好多不同的做法都可以 ...

  3. 【BZOJ1500】【块状链表】维修数列

    Description Input 输入文件的第1行包含两个数N和M,N表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一条命令,格式参见问题描述 ...

  4. 【BZOJ2741】【块状链表+可持久化trie】FOTILE模拟赛L

    Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 .. ...

  5. 【BZOJ3295】【块状链表+树状数组】动态逆序对

    Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计 ...

  6. 【HDU4391】【块状链表】Paint The Wall

    Problem Description As a amateur artist, Xenocide loves painting the wall. The wall can be considere ...

  7. luogu P4008 [NOI2003]文本编辑器 splay 块状链表

    LINK:文本编辑器 这个东西感觉块状链表写细节挺多 (块状链表本来就难写 解释一下块状链表的做法:其实是一个个数组块 然后利用链表给链接起来 每个块的大小为sqrt(n). 这样插入删除的时候直接暴 ...

  8. 【BZOJ-1507】Editor 块状链表

    1507: [NOI2003]Editor Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 3397  Solved: 1360[Submit][Stat ...

  9. ZOJ 2112 Dynamic Rankings(动态区间第 k 大+块状链表)

    题目大意 给定一个数列,编号从 1 到 n,现在有 m 个操作,操作分两类: 1. 修改数列中某个位置的数的值为 val 2. 询问 [L, R] 这个区间中第 k 大的是多少 n<=50,00 ...

随机推荐

  1. 可恶的0x1A

    很少用fread读文件,今天用fread读一个文件死活缺一点,折腾半天才发现原来遇到0x1a. 0x1a 是 Ctrl+Z ,是模拟文件结束的符号,就是文件遇到0x1a后,认为文件已经结束. 哎!记下

  2. 265行JavaScript代码的第一人称3D H5游戏Demo【个人总结1】

    本文目的是分解前面的代码.其实,它得逻辑很清楚,只是对于我这种只是用过 Canvas 画线(用过 Fabric.js Canvas库)的人来说,这个还是很复杂的.我研究这个背景天空也是搞了一天,下面就 ...

  3. [IoLanguage]Io Programming Guide[转]

    Io Programming Guide     Introduction Perspective Getting Started Downloading Installing Binaries Ru ...

  4. wikioi 1154 能量项链 (2006年NOIP全国联赛提高组)

    题目描述 Description 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子 ...

  5. Oracle Hint 详解

    Hint 是Oracle 提供的一种SQL语法,它允许用户在SQL语句中插入相关的语法,从而影响SQL的执行方式. 因为Hint的特殊作用,所以对于开发人员不应该在代码中使用它,Hint 更像是Ora ...

  6. [Redux] Navigating with React Router <Link>

    We will learn how to change the address bar using a component from React Router. In Root.js: We need ...

  7. BZOJ 2525 Poi2011 Dynamite 二分答案+树形贪心

    题目大意:给定一棵树,有一些点是关键点,要求选择不超过mm个点.使得全部关键点到近期的选择的点距离最大值最小 二分答案,问题转化为: 给定一棵树,有一些点是关键点,要求选择最少的点使得每一个关键点到选 ...

  8. 学习NodeJS第一天:node.js引言

    Node.JS 是资深 C 程序猿 Ryan Dahl(http://four.livejournal.com/)的作品,根据 Google 著名的开源 JavaScript 引擎 V8 来进行二次开 ...

  9. 安全通信 QSslSocket

    The QSslSocket class provides an SSL encrypted socket for both clients and servers. More... Header: ...

  10. MapReduce 运行机制

    Hadoop中的MapReduce是一个使用简单的软件框架,基于它写出来的应用程序能够运行在由上千个机器组成的大型集群上,并且以一种可靠容错并行处理TB级别的数据集. 一个MapReduce作业(jo ...