给一个字符串,有两个操作:查询第i个字符,在第i个字符前加入一个其他字符
可以用块状链表 以根号n为块大小,复杂度为每次操作根号n
#include <cstdio>
#include <cstring>
using namespace std;
const int SIZE=1010;
struct Node {
char a[SIZE*2];
Node *next;
int length;
void push_back(char c) {
a[length++]=c;
}
void add(int x,char c) {
for (int i=length;i>x;i--) a[i]=a[i-1];
a[x]=c;
length++;
}
};
struct BlockList {
Node a[SIZE];
Node *head;
int length,p;
BlockList() {
memset(a,0,sizeof(a));
length=0;
p=0;
head=NULL;
}
void read() {
head=&a[0];
char c;
while (c=getchar(),c!='\n') {
length++;
if (a[p].length>=SIZE) p++;
a[p].push_back(c);
}
for (int i=0;i<p;i++) a[i].next=&a[i+1];
p++;
}
void check(Node *x) {
if (x->length==SIZE*2) {
Node *y=&a[p++];
y->next=x->next;
x->next=y;
y->length=x->length=SIZE;
for (int i=0;i<SIZE;i++) {
y->a[i]=x->a[i+SIZE];
}
}
}
void add(int x,char c) {
length++;
Node *cur=head;
while (x>=cur->length) {
x-=cur->length;
cur=cur->next;
}
cur->add(x,c);
check(cur);
}
void push_back(char c) {
length++;
if (head==NULL) {
head=&a[p++];
head->length=1;
head->next=NULL;
head->a[0]=c;
} else {
Node *cur=head;
while (cur->next) cur=cur->next;
cur->push_back(c);
check(cur);
}
}
char &operator [] (int x) {
Node *cur=head;
while (x>=cur->length) {
x-=cur->length;
cur=cur->next;
}
return cur->a[x];
}
void print() {
printf("-- BlockList:\n");
printf(" length:%d, with %d blocks\n ",length,p);
Node *cur=head;
while (cur!=NULL) {
for (int i=0;i<cur->length;i++) printf("%c",cur->a[i]);
cur=cur->next;
}
printf("\n Each block has: ");
cur=head;
while (cur!=NULL) {
printf("%d ",cur->length);
cur=cur->next;
}
printf("\n");
}
};
BlockList a;
int n;
int main() {
char c;
int x;
a.read();
/*
while (c=getchar(),c!='\n') {
a.push_back(c);
//a.print();
}
*/
//a.print();
scanf("%d",&n);
while (n--) {
scanf(" %c",&c);
if (c=='Q') {
scanf("%d",&x);
printf("%c\n",a[x-1]);
} else {
scanf(" %c%d",&c,&x);
if (x<=a.length) a.add(x-1,c);
else a.push_back(c);
}
//a.print();
}
return 0;
}