rt, wa on #1, #6, #7, #8, #9, #10
// Problem: P4008 [NOI2003] 文本编辑器
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P4008
// Memory Limit: 125 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
int m = 0, tp, k;
int N = 2500;
list <vector<char>> l;
typedef list<vector<char>>::iterator lit;
lit find(int &p) {
for (lit it = l.begin(); ;it ++ ) {
if (it == l.end() || p <= it->size())
return it;
p -= it->size();
}
}
void get(int L, int R) {
lit fl = find(L), fr = find(R);
for (lit it = fl; ; it ++ ) {
int x = (it == fl) ? L : 0;
int y = (it == fr) ? R : it->size();
for (int i = x; i < y; i ++ )
putchar(it->at(i));
if (it == fr) break;
}
puts("");
}
lit nxt(lit x) {return ++ x;}
void merge(lit x) {
x->insert(x->end(), nxt(x)->begin(), nxt(x)->end());
l.erase(nxt(x));
}
void split(lit x, int p) {
if (p == x->size()) return ;
l.insert(nxt(x), vector<char>(x->begin() + p, x->end()));
x->erase(x->begin() + p, x->end());
}
void upd() {
for (lit x = l.begin(); x != l.end(); x ++ ) {
while (x->size() >= (N << 1))
split(x, x->size() - N);
while (nxt(x) != l.end() &&
x->size() + nxt(x)->size() <= N)
merge(x);
while (nxt(x) != l.end() && nxt(x)->empty())
l.erase(nxt(x));
}
}
void insert(int x, vector <char> ch) {
lit p = find(x);
if (l.size()) split(p, x);
l.insert(nxt(p), ch);
upd();
}
void del(int L, int R) {
lit fl = find(L), fr = find(R);
split(fr, R); split(fl, L);
// 如果先find再一起分离就要先r后l
// 如果find(l), split(l), find(r), split(r)则不用
++ fr;
while (nxt(fl) != fr) l.erase(nxt(fl));
upd();
}
signed main(){
scanf("%d", &m);
vector <char> ch;
while (m -- ) {
char op[7]; scanf("%s", op);
char c = op[0];
if (c == 'M') scanf("%d", &k);
if (c == 'I') {
int p;
scanf("%d", &p);
ch.clear();
ch.resize(p);
ch[0] = getchar();
for (int i = 0; i < p; i ++ ) {
ch[i] = getchar();
while (ch[i] < 32 || ch[i] > 126)
ch[i] = getchar();
}
insert(k, ch);
}
if (c == 'G') {
scanf("%d", &tp);
get(k, k + tp);
}
if (c == 'D') {
scanf("%d", &tp);
del(k, k + tp);
}
if (c == 'P') k -- ;
if (c == 'N') k ++ ;
}
return 0;
}