「Editor」

Assuming that the string is initially empty, the basic operations that can be performed are append/insert/delete/replace, as described below:

append: Appends a string of the specified length to the string.
insert: Inserts a string of the specified length at the specified position of an existing string.
delete: Removes a specified length of characters from an existing string at a specified location.
replace: Replaces a number of characters at a specified position in an existing string with another string.

字符串的位置从 1 开始计数
字符串中的字符,只能是 a-z、A-Z、0-9
每行由一个基本操作+后续参数组成,每种操作的参数不同,用冒号分隔
append:两个参数,分别是要追加字符串的长度、具体的字符串内容
insert:三个参数,分别是插入位置、要插入字符串的长度、具体的内容
delete:两个参数,分别是删除位置,要删除的字符个数
replace:四个参数,分别是替换位置,被替换长度,替换长度,具体的内容

样例:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
append : 12 : abcdefghijkl # 操作完成后,字符串为 "abcdefghijkl"
append : 10 : ABCDEFGHIJ # 操作完成后,字符串为 "abcdefghijklABCDEFGHIJ"
#insert : 9 : 2 : pq # 本行忽略(忽略#开头的行)
insert : 2 : 3 : XYZ # 操作完成后,字符串为 "aXYZbcdefghijklABCDEFGHIJ"
delete : 10 : 2 # 操作完成后,字符串为 "aXYZbcdefijklABCDEFGHIJ"
replace : 7 : 3 : 10 : 0123456789 # 操作完成后,字符串为 "aXYZbc0123456789ijklABCDEFGHIJ"
append : 12 : abcdefghijkl # 操作完成后,字符串为 "abcdefghijkl" append : 10 : ABCDEFGHIJ # 操作完成后,字符串为 "abcdefghijklABCDEFGHIJ" #insert : 9 : 2 : pq # 本行忽略(忽略#开头的行) insert : 2 : 3 : XYZ # 操作完成后,字符串为 "aXYZbcdefghijklABCDEFGHIJ" delete : 10 : 2 # 操作完成后,字符串为 "aXYZbcdefijklABCDEFGHIJ" replace : 7 : 3 : 10 : 0123456789 # 操作完成后,字符串为 "aXYZbc0123456789ijklABCDEFGHIJ"
append : 12 : abcdefghijkl             # 操作完成后,字符串为 "abcdefghijkl"
append : 10 : ABCDEFGHIJ          # 操作完成后,字符串为 "abcdefghijklABCDEFGHIJ"
#insert : 9 : 2 : pq                           # 本行忽略(忽略#开头的行)
insert : 2 : 3 : XYZ                          # 操作完成后,字符串为 "aXYZbcdefghijklABCDEFGHIJ"
delete : 10 : 2                                   # 操作完成后,字符串为 "aXYZbcdefijklABCDEFGHIJ"
replace : 7 : 3 : 10 : 0123456789  # 操作完成后,字符串为 "aXYZbc0123456789ijklABCDEFGHIJ"

代码:

块状链表随便乱搞了一下就好了

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cctype>
#include <cstring>
#include <string>
#define MAXIN 1
#define gc() (SS == TT && (TT = (SS = IN) + fread(IN,1,MAXIN,stdin),SS == TT) ? -1 : *SS++)
int N, qqq;
const int M = 1024 * 1024 * 1 + 5;
int maxsize = 40000, maxnum;
int num, *next, *sz, *pool;
char **data, str[M], IN[MAXIN], *SS = IN, *TT = IN;
char *pre;
inline int read()
{
int now = 0, f = 1;
register char c = gc();
for (; !isdigit(c); c = gc())
if (c == '-')
f = -1;
for (; isdigit(c);
now = now * 10 + c - '0', c = gc());
return now * f;
}
inline int new_block()
{
return pool[++num];
}
inline void del_block(int v)
{
pool[num--] = v;
}
void init()
{
for (int i = 1; i < maxnum; ++i)
pool[i] = i;
sz[0] = 0; //新建一个0节点,方便 表头就是0
next[0] = -1;
}
void merge(int cur, int Next)
{
memcpy(data[cur] + sz[cur], data[Next], sz[Next]);
next[cur] = next[Next];
sz[cur] += sz[Next];
del_block(Next);
}
void maintain()
{
for (int cur = 0, Next = next[0]; ~cur; cur = next[cur], Next = next[cur])
while ((~Next) && sz[cur] + sz[Next] <= maxsize)
{
merge(cur, Next);//最好不用next[Next],因为已经合并、删掉了
Next = next[cur];
}
}
int get_index(int &pos) //找到pos所在的块,并将pos定位为块内位置
{
int cur = 0;
while ((~cur) && pos > sz[cur]) //把cur定位到某一块的末尾,不用下一块开头了(pos>=sz)
{
pos -= sz[cur];
cur = next[cur];
}
return cur;
}
void update(int cur, int Next, int len, char *s)//给新的块Next设置数据及指针
{
next[Next] = next[cur];
next[cur] = Next;
sz[Next] = len;
memcpy(data[Next], s, len);
}
void split(int cur, int pos)
{
if (cur == -1 || pos == sz[cur])//不能判!pos 因为后边会直接用next[cur],不分裂会跳过该块
return;
int Next = new_block();
update(cur, Next, sz[cur] - pos, data[cur] + pos);
sz[cur] = pos;
}
void insert(int pos, int len)
{
int cur = get_index(pos), sum = 0, Next;
split(cur, pos);
while (sum + maxsize <= len)
{
Next = new_block();
update(cur, Next, maxsize, str + sum);//先分成尽可能多的整块
sum += maxsize;
cur = Next;
}
if (len - sum) //剩余的单独放到一块
Next = new_block(), update(cur, Next, len - sum, str + sum);
maintain();
}
void erase(int pos, int len)
{
int cur = get_index(pos), Next;
split(cur, pos);
Next = next[cur]; //because of here
while ((~Next) && len > sz[Next])
len -= sz[Next], del_block(Next), Next = next[Next];
split(Next, len);
del_block(Next), next[cur] = next[Next];
maintain();
}
void get_data(int pos, int len)
{
delete[]pre;
int cur = get_index(pos), sum = sz[cur] - pos;
if (len < sum)
sum = len;
//memcpy(str, data[cur] + pos, sum);
fwrite(data[cur] + pos, sizeof(char), sum, stdout);
cur = next[cur];
while ((~cur) && sum + sz[cur] <= len)
{
//memcpy(str + sum, data[cur], sz[cur]);
fwrite(data[cur], sizeof(char), sz[cur], stdout);
sum += sz[cur];
cur = next[cur];
}
if ((~cur) && len - sum)
fwrite(data[cur], sizeof(char), len - sum, stdout);
//memcpy(str + sum, data[cur], len - sum);
//str[len] = '\0';
//printf("%s", str);
}
bool alloc(int size)
{
next = new(std::nothrow) int[size];
if (next == NULL)
return false;
sz = new(std::nothrow) int[size];
if (sz == NULL)
return false;
pool = new(std::nothrow) int[size];
if (pool == NULL)
return false;
data = new(std::nothrow) char*[size];
if (data == NULL)
return false;
for (int i = 0; i < size; ++i)
{
data[i] = new(std::nothrow) char[maxsize];
qqq = i;
if (data[i] == NULL)
return false;
}
return true;
}
int main()
{
freopen("input.txt", "rb", stdin);
freopen("output.txt", "wb", stdout);
fseek(stdin, 0L, SEEK_END);
N = ftell(stdin);
fseek(stdin, 0L, SEEK_SET);
maxnum = N * 2 / maxsize + 100;
pre = new(std::nothrow) char[M];
int left = 1, right = maxnum, mid = (left + right) / 2;
while (1)
{
if (left == mid || right == mid)
{
maxnum = mid;
break;
}
if (alloc(mid) == true)
{
delete[]next;
delete[]sz;
delete[]pool;
for (int i = 0; i < mid; ++i)
delete[]data[i];
delete[]data;
left = mid;
mid = (left + right) / 2;
}
else
{
delete[]next;
delete[]sz;
delete[]pool;
for (int i = 0; i < qqq; ++i)
delete[]data[i];
delete[]data;
right = mid;
mid = (left + right) / 2;
}
}
alloc(maxnum);
int limit;
if (maxnum > 200)
limit = (maxnum - 100)*maxsize / 2;
else
limit = 100 * maxsize / 2;
init();
int pos = 0, len, tot = 0;
char c;
while (1)
{
c = gc();
if (c == -1)
break;
if (c == 'a')
{
len = read();
if (len + tot > limit)
{
get_data(0, tot);
return 0;
}
while (1)
{
char ch = gc();
if (isdigit(ch) || islower(ch) || isupper(ch))
{
str[0] = ch;
break;
}
}
fread(str + 1, sizeof(char)*(len - 1), 1, stdin);
insert(tot, len);
tot += len;
//get_data(0, tot);
while (gc() != '\n')
;
}
else if (c == 'i')
{
pos = read();
len = read();
if (len + tot > limit)
{
get_data(0, tot);
return 0;
}
while (1)
{
char ch = gc();
if (isdigit(ch) || islower(ch) || isupper(ch))
{
str[0] = ch;
break;
}
}
fread(str + 1, sizeof(char), len - 1, stdin);
insert(pos - 1, len);
tot += len;
//get_data(0, tot);
while (gc() != '\n')
;
}
else if (c == 'd')
{
pos = read();
len = read();
erase(pos - 1, len);
tot -= len;
//get_data(0, tot);
}
else if (c == 'r')
{
pos = read();
len = read();
erase(pos - 1, len);
tot -= len;
len = read();
if (len + tot > limit)
{
get_data(0, tot);
return 0;
}
tot += len;
while (1)
{
char ch = gc();
if (isdigit(ch) || islower(ch) || isupper(ch))
{
str[0] = ch;
break;
}
}
fread(str + 1, sizeof(char), len - 1, stdin);
insert(pos - 1, len);
//get_data(0, tot);
while (gc() != '\n')
;
}
else if (c == '#')
while (gc() != '\n')
;
}
get_data(0, tot);
fclose(stdout);
fclose(stdin);
return 0;
}
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cctype> #include <cstring> #include <string> #define MAXIN 1 #define gc() (SS == TT && (TT = (SS = IN) + fread(IN,1,MAXIN,stdin),SS == TT) ? -1 : *SS++) int N, qqq; const int M = 1024 * 1024 * 1 + 5; int maxsize = 40000, maxnum; int num, *next, *sz, *pool; char **data, str[M], IN[MAXIN], *SS = IN, *TT = IN; char *pre; inline int read() { int now = 0, f = 1; register char c = gc(); for (; !isdigit(c); c = gc()) if (c == '-') f = -1; for (; isdigit(c); now = now * 10 + c - '0', c = gc()); return now * f; } inline int new_block() { return pool[++num]; } inline void del_block(int v) { pool[num--] = v; } void init() { for (int i = 1; i < maxnum; ++i) pool[i] = i; sz[0] = 0; //新建一个0节点,方便 表头就是0 next[0] = -1; } void merge(int cur, int Next) { memcpy(data[cur] + sz[cur], data[Next], sz[Next]); next[cur] = next[Next]; sz[cur] += sz[Next]; del_block(Next); } void maintain() { for (int cur = 0, Next = next[0]; ~cur; cur = next[cur], Next = next[cur]) while ((~Next) && sz[cur] + sz[Next] <= maxsize) { merge(cur, Next);//最好不用next[Next],因为已经合并、删掉了 Next = next[cur]; } } int get_index(int &pos) //找到pos所在的块,并将pos定位为块内位置 { int cur = 0; while ((~cur) && pos > sz[cur]) //把cur定位到某一块的末尾,不用下一块开头了(pos>=sz) { pos -= sz[cur]; cur = next[cur]; } return cur; } void update(int cur, int Next, int len, char *s)//给新的块Next设置数据及指针 { next[Next] = next[cur]; next[cur] = Next; sz[Next] = len; memcpy(data[Next], s, len); } void split(int cur, int pos) { if (cur == -1 || pos == sz[cur])//不能判!pos 因为后边会直接用next[cur],不分裂会跳过该块 return; int Next = new_block(); update(cur, Next, sz[cur] - pos, data[cur] + pos); sz[cur] = pos; } void insert(int pos, int len) { int cur = get_index(pos), sum = 0, Next; split(cur, pos); while (sum + maxsize <= len) { Next = new_block(); update(cur, Next, maxsize, str + sum);//先分成尽可能多的整块 sum += maxsize; cur = Next; } if (len - sum) //剩余的单独放到一块 Next = new_block(), update(cur, Next, len - sum, str + sum); maintain(); } void erase(int pos, int len) { int cur = get_index(pos), Next; split(cur, pos); Next = next[cur]; //because of here while ((~Next) && len > sz[Next]) len -= sz[Next], del_block(Next), Next = next[Next]; split(Next, len); del_block(Next), next[cur] = next[Next]; maintain(); } void get_data(int pos, int len) { delete[]pre; int cur = get_index(pos), sum = sz[cur] - pos; if (len < sum) sum = len; //memcpy(str, data[cur] + pos, sum); fwrite(data[cur] + pos, sizeof(char), sum, stdout); cur = next[cur]; while ((~cur) && sum + sz[cur] <= len) { //memcpy(str + sum, data[cur], sz[cur]); fwrite(data[cur], sizeof(char), sz[cur], stdout); sum += sz[cur]; cur = next[cur]; } if ((~cur) && len - sum) fwrite(data[cur], sizeof(char), len - sum, stdout); //memcpy(str + sum, data[cur], len - sum); //str[len] = '\0'; //printf("%s", str); } bool alloc(int size) { next = new(std::nothrow) int[size]; if (next == NULL) return false; sz = new(std::nothrow) int[size]; if (sz == NULL) return false; pool = new(std::nothrow) int[size]; if (pool == NULL) return false; data = new(std::nothrow) char*[size]; if (data == NULL) return false; for (int i = 0; i < size; ++i) { data[i] = new(std::nothrow) char[maxsize]; qqq = i; if (data[i] == NULL) return false; } return true; } int main() { freopen("input.txt", "rb", stdin); freopen("output.txt", "wb", stdout); fseek(stdin, 0L, SEEK_END); N = ftell(stdin); fseek(stdin, 0L, SEEK_SET); maxnum = N * 2 / maxsize + 100; pre = new(std::nothrow) char[M]; int left = 1, right = maxnum, mid = (left + right) / 2; while (1) { if (left == mid || right == mid) { maxnum = mid; break; } if (alloc(mid) == true) { delete[]next; delete[]sz; delete[]pool; for (int i = 0; i < mid; ++i) delete[]data[i]; delete[]data; left = mid; mid = (left + right) / 2; } else { delete[]next; delete[]sz; delete[]pool; for (int i = 0; i < qqq; ++i) delete[]data[i]; delete[]data; right = mid; mid = (left + right) / 2; } } alloc(maxnum); int limit; if (maxnum > 200) limit = (maxnum - 100)*maxsize / 2; else limit = 100 * maxsize / 2; init(); int pos = 0, len, tot = 0; char c; while (1) { c = gc(); if (c == -1) break; if (c == 'a') { len = read(); if (len + tot > limit) { get_data(0, tot); return 0; } while (1) { char ch = gc(); if (isdigit(ch) || islower(ch) || isupper(ch)) { str[0] = ch; break; } } fread(str + 1, sizeof(char)*(len - 1), 1, stdin); insert(tot, len); tot += len; //get_data(0, tot); while (gc() != '\n') ; } else if (c == 'i') { pos = read(); len = read(); if (len + tot > limit) { get_data(0, tot); return 0; } while (1) { char ch = gc(); if (isdigit(ch) || islower(ch) || isupper(ch)) { str[0] = ch; break; } } fread(str + 1, sizeof(char), len - 1, stdin); insert(pos - 1, len); tot += len; //get_data(0, tot); while (gc() != '\n') ; } else if (c == 'd') { pos = read(); len = read(); erase(pos - 1, len); tot -= len; //get_data(0, tot); } else if (c == 'r') { pos = read(); len = read(); erase(pos - 1, len); tot -= len; len = read(); if (len + tot > limit) { get_data(0, tot); return 0; } tot += len; while (1) { char ch = gc(); if (isdigit(ch) || islower(ch) || isupper(ch)) { str[0] = ch; break; } } fread(str + 1, sizeof(char), len - 1, stdin); insert(pos - 1, len); //get_data(0, tot); while (gc() != '\n') ; } else if (c == '#') while (gc() != '\n') ; } get_data(0, tot); fclose(stdout); fclose(stdin); return 0; }
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cctype>
#include <cstring>
#include <string>

#define MAXIN 1
#define gc() (SS == TT && (TT = (SS = IN) + fread(IN,1,MAXIN,stdin),SS == TT) ? -1 : *SS++)
int N, qqq;
const int M = 1024 * 1024 * 1 + 5;
int maxsize = 40000, maxnum;

int num, *next, *sz, *pool;
char **data, str[M], IN[MAXIN], *SS = IN, *TT = IN;
char *pre;

inline int read()
{
	int now = 0, f = 1;
	register char c = gc();
	for (; !isdigit(c); c = gc())
		if (c == '-')
			f = -1;
	for (; isdigit(c);
		now = now * 10 + c - '0', c = gc());
	return now * f;
}

inline int new_block()
{
	return pool[++num];
}

inline void del_block(int v)
{
	pool[num--] = v;
}

void init()
{
	for (int i = 1; i < maxnum; ++i)
		pool[i] = i;
	sz[0] = 0;			//新建一个0节点,方便 表头就是0 
	next[0] = -1;
}

void merge(int cur, int Next)
{
	memcpy(data[cur] + sz[cur], data[Next], sz[Next]);
	next[cur] = next[Next];
	sz[cur] += sz[Next];
	del_block(Next);
}

void maintain()
{
	for (int cur = 0, Next = next[0]; ~cur; cur = next[cur], Next = next[cur])
		while ((~Next) && sz[cur] + sz[Next] <= maxsize)
		{
			merge(cur, Next);//最好不用next[Next],因为已经合并、删掉了
			Next = next[cur];
		}
}

int get_index(int &pos)			//找到pos所在的块,并将pos定位为块内位置 
{
	int cur = 0;
	while ((~cur) && pos > sz[cur])	//把cur定位到某一块的末尾,不用下一块开头了(pos>=sz) 
	{
		pos -= sz[cur];
		cur = next[cur];
	}
	return cur;
}

void update(int cur, int Next, int len, char *s)//给新的块Next设置数据及指针 
{
	next[Next] = next[cur];
	next[cur] = Next;
	sz[Next] = len;
	memcpy(data[Next], s, len);
}

void split(int cur, int pos)
{
	if (cur == -1 || pos == sz[cur])//不能判!pos 因为后边会直接用next[cur],不分裂会跳过该块
		return;
	int Next = new_block();
	update(cur, Next, sz[cur] - pos, data[cur] + pos);
	sz[cur] = pos;
}

void insert(int pos, int len)
{
	int cur = get_index(pos), sum = 0, Next;
	split(cur, pos);
	while (sum + maxsize <= len)
	{
		Next = new_block();
		update(cur, Next, maxsize, str + sum);//先分成尽可能多的整块 
		sum += maxsize;
		cur = Next;
	}
	if (len - sum)				//剩余的单独放到一块 
		Next = new_block(), update(cur, Next, len - sum, str + sum);
	maintain();
}

void erase(int pos, int len)
{
	int cur = get_index(pos), Next;
	split(cur, pos);
	Next = next[cur];			//because of here
	while ((~Next) && len > sz[Next])
		len -= sz[Next], del_block(Next), Next = next[Next];
	split(Next, len);
	del_block(Next), next[cur] = next[Next];
	maintain();
}

void get_data(int pos, int len)
{
	delete[]pre;
	int cur = get_index(pos), sum = sz[cur] - pos;
	if (len < sum)
		sum = len;
	//memcpy(str, data[cur] + pos, sum);
	fwrite(data[cur] + pos, sizeof(char), sum, stdout);

	cur = next[cur];
	while ((~cur) && sum + sz[cur] <= len)
	{
		//memcpy(str + sum, data[cur], sz[cur]);
		fwrite(data[cur], sizeof(char), sz[cur], stdout);
		sum += sz[cur];
		cur = next[cur];
	}
	if ((~cur) && len - sum)
		fwrite(data[cur], sizeof(char), len - sum, stdout);
	//memcpy(str + sum, data[cur], len - sum);
	//str[len] = '\0';
	//printf("%s", str);
}

bool alloc(int size)
{
	next = new(std::nothrow) int[size];
	if (next == NULL)
		return false;
	sz = new(std::nothrow) int[size];
	if (sz == NULL)
		return false;
	pool = new(std::nothrow) int[size];
	if (pool == NULL)
		return false;

	data = new(std::nothrow) char*[size];
	if (data == NULL)
		return false;
	for (int i = 0; i < size; ++i)
	{
		data[i] = new(std::nothrow) char[maxsize];
		qqq = i;
		if (data[i] == NULL)
			return false;
	}
	return true;
}

int main()
{
	freopen("input.txt", "rb", stdin);
	freopen("output.txt", "wb", stdout);

	fseek(stdin, 0L, SEEK_END);
	N = ftell(stdin);
	fseek(stdin, 0L, SEEK_SET);
	maxnum = N * 2 / maxsize + 100;

	pre = new(std::nothrow) char[M];

	int left = 1, right = maxnum, mid = (left + right) / 2;
	while (1)
	{
		if (left == mid || right == mid)
		{
			maxnum = mid;
			break;
		}
		if (alloc(mid) == true)
		{
			delete[]next;
			delete[]sz;
			delete[]pool;
			for (int i = 0; i < mid; ++i)
				delete[]data[i];
			delete[]data;
			left = mid;
			mid = (left + right) / 2;
		}
		else
		{
			delete[]next;
			delete[]sz;
			delete[]pool;
			for (int i = 0; i < qqq; ++i)
				delete[]data[i];
			delete[]data;
			right = mid;
			mid = (left + right) / 2;
		}
	}

	alloc(maxnum);
	int limit;
	if (maxnum > 200)
		limit = (maxnum - 100)*maxsize / 2;
	else
		limit = 100 * maxsize / 2;

	init();
	int pos = 0, len, tot = 0;
	char c;
	while (1)
	{
		c = gc();
		if (c == -1)
			break;
		if (c == 'a')
		{
			len = read();
			if (len + tot > limit)
			{
				get_data(0, tot);
				return 0;
			}
			while (1)
			{
				char ch = gc();
				if (isdigit(ch) || islower(ch) || isupper(ch))
				{
					str[0] = ch;
					break;
				}
			}
			fread(str + 1, sizeof(char)*(len - 1), 1, stdin);
			insert(tot, len);
			tot += len;
			//get_data(0, tot);

			while (gc() != '\n')
				;
		}
		else if (c == 'i')
		{
			pos = read();
			len = read();
			if (len + tot > limit)
			{
				get_data(0, tot);
				return 0;
			}
			while (1)
			{
				char ch = gc();
				if (isdigit(ch) || islower(ch) || isupper(ch))
				{
					str[0] = ch;
					break;
				}
			}
			fread(str + 1, sizeof(char), len - 1, stdin);
			insert(pos - 1, len);
			tot += len;
			//get_data(0, tot);

			while (gc() != '\n')
				;
		}
		else if (c == 'd')
		{
			pos = read();
			len = read();
			erase(pos - 1, len);
			tot -= len;
			//get_data(0, tot);

		}
		else if (c == 'r')
		{
			pos = read();
			len = read();
			erase(pos - 1, len);
			tot -= len;
			len = read();
			if (len + tot > limit)
			{
				get_data(0, tot);
				return 0;
			}
			tot += len;
			while (1)
			{
				char ch = gc();
				if (isdigit(ch) || islower(ch) || isupper(ch))
				{
					str[0] = ch;
					break;
				}
			}
			fread(str + 1, sizeof(char), len - 1, stdin);
			insert(pos - 1, len);
			//get_data(0, tot);

			while (gc() != '\n')
				;
		}
		else if (c == '#')
			while (gc() != '\n')
				;
	}

	get_data(0, tot);

	fclose(stdout);
	fclose(stdin);
	return 0;
}

 

Add a Comment

Your email address will not be published. Required fields are marked *