题目:
http://www.lydsy.com/JudgeOnline/problem.php?id=1507
题意:
思路:
用块状链表写的,操作还是挺繁琐的。。。
#include <bits/stdc++.h>
using namespace std;
const int N = 4000000 + 10, M = 3000+10;
const int block_num = 3000 + 100;
queue<int> que;
int head;
char str[N];
struct block
{
int sz, next;
char s[M];
void init()
{
sz = 0, next = -1;
}
}g[block_num];
int new_block()
{
int t = que.front(); que.pop();
g[t].init();
return t;
}
void del_block(int t)
{
que.push(t);
}
void block_init()
{
while(! que.empty()) que.pop();
for(int i = 0; i < block_num; i++) que.push(i);
head = new_block();
}
void block_split(int idx, int k) //把块分裂
{
if(g[idx].sz == k) return;
int tot = new_block();
memcpy(g[tot].s, g[idx].s + k, sizeof(char) * (g[idx].sz - k));
g[tot].sz = g[idx].sz - k, g[idx].sz = k;
g[tot].next = g[idx].next, g[idx].next = tot;
}
void block_locate(int &idx, int &k)
{
while(idx != -1 && k > g[idx].sz)
k -= g[idx].sz, idx = g[idx].next;
}
void block_merge(int idx) //合并零碎的块
{
for(int i = idx; i != -1; i = g[i].next)
{
for(int j = g[i].next; j != -1; j = g[j].next)
{
if(g[i].sz + g[j].sz <= M)
{
memcpy(g[i].s + g[i].sz, g[j].s, sizeof(char) * g[j].sz);
g[i].sz += g[j].sz, g[i].next = g[j].next;
del_block(j);
}
else break;
}
}
}
void block_insert(int k, int n, char *str)
{
int idx = head;
block_locate(idx, k);
block_split(idx, k);
int i = 0;
while(i < n)
{
int sz = min(M, n - i);
int tot = new_block();
memcpy(g[tot].s, str + i, sizeof(char) * sz);
g[tot].sz = sz;
g[tot].next = g[idx].next, g[idx].next = tot;
idx = g[idx].next;
i += sz;
}
block_merge(head);
}
void block_delete_str(int k, int n)
{
int idx = head, tk = k;
block_locate(idx, tk);
block_split(idx, tk);
int st = idx, st_next = g[idx].next;
idx = head, tk = k + n;
block_locate(idx, tk);
block_split(idx, tk);
int en = idx, en_next = g[idx].next;
for(int i = st_next; i != en_next; i = g[i].next) del_block(i);
g[st].next = en_next;
block_merge(head);
}
void block_print(int k, int n, char *str)
{
int idx = head;
block_locate(idx, k);
int len = 0;
for(int i = idx; i != -1 && n > 0; i = g[i].next)
{
int sz = min(n, g[i].sz - k);
memcpy(str + len, g[i].s + k, sizeof(char) * sz);
len += sz, n -= sz;
k = 0;
}
str[len] = '\0';
puts(str);
}
int main()
{
int t, cur = 0;
char op[20];
block_init();
scanf("%d", &t);
for(int i = 1; i <= t; i++)
{
scanf("%s", op);
if(op[0] == 'M')
{
int k;
scanf("%d", &k);
cur = k;
}
else if(op[0] == 'I')
{
int n;
scanf("%d", &n);
int j = 0;
while(j < n)
{
char ch = getchar();
if(ch >= 32 && ch <= 126) str[j++] = ch;
}
block_insert(cur, n, str);
}
else if(op[0] == 'D')
{
int n;
scanf("%d", &n);
block_delete_str(cur, n);
}
else if(op[0] == 'G')
{
int n;
scanf("%d", &n);
block_print(cur, n, str);
}
else if(op[0] == 'P') cur--;
else if(op[0] == 'N') cur++;
}
return 0;
}
另:rope大法好
#include <bits/stdc++.h>
#include <ext/rope>
using namespace std;
using namespace __gnu_cxx;
const int N = 2000000 + 10;
rope<char> rs;
char str[N];
int main()
{
int n, m, cur = 0;
char op[20];
scanf("%d", &n);
while(n--)
{
scanf("%s", op);
if(op[0] == 'M') scanf("%d", &cur);
else if(op[0] == 'I')
{
scanf("%d", &m);
int i = 0;
while(i < m)
{
char ch = getchar();
if(ch >= 32 && ch <= 126) str[i++] = ch;
}
str[i] = '\0';
int len = rs.size();
rs.insert(cur, str);
}
else if(op[0] == 'D')
{
scanf("%d", &m);
rs.erase(cur, m);
}
else if(op[0] == 'G')
{
scanf("%d", &m);
printf("%s\n", rs.substr(cur, m).c_str());
}
else if(op[0] == 'P') cur--;
else if(op[0] == 'N') cur++;
}
return 0;
}