rope大法好!

基本

是 $ ext $ 里面的一个 $ stl $ ,所以万能头重没有这个 $ stl $ ,要用新的头文件

$ rope $ 里面可以用 $ char $ , $ int $ , $ long long $ , $ double $ 。但是不能用 $ pair<int,int> $ !

#include<ext/rope>
using namespace __gnu_cxx

$ rope $ 的实现是可持久化平衡树,但是没有办法处理像可持久化数据结构模板题那种第 $ k $ 大数的问题

rope的函数

#include<ext/rope>
using namespace __gnu_cxx;

rope<int> h;
rope<int> w[N];
char c[N];

h.push_back(x); // 增加元素
h.insert(pos,s);
// 在pos这个位置插入x这个值,然后把原先的值都往后推
h.erase(pos,len);
// 从pos开始删去len个元素
h.size(); // 大小
h.replace(pos,x); // 替换
h.substr(pos,len); 
// 从pos开始提出len个
h.copy(pos,len,c);
// 从pos开始提出len个复制到c中,这里的c不能是string!!
h[x]/h.at(x);

指针复制 $ O(1) $ ,数组复制 $ O(n) $ ,其它操作 $ O(logn) $

注意点

rope内部其实还是字符串,只不过我们习惯性的用int,所以用数组初始化的时候要注意一下

例题

P3919 可持久化线段树1 (可持久化数组)

核心代码

rope<int> *w[N];
w[0] = new rope<int>(-1);
for (int i = 1; i <= n; i ++) {
	a = fr();
	w[0]->push_back(a);
}
for (int i = 1; i <= m; i ++) {
	if (type == 1) {
		w[i] = new rope<int>(*w[k]);
		w[i]->replace(loc,val);
	} else {
		w[i] = new rope<int>(*w[k]);
		fw(w[i]->at(loc));
	}
}

P4008 文本编辑器

这个输入有亿点点阴间,核心代码

rope<char> w;
int pos = 0;
for (int i = 1; i <= T; i ++) {
	cin >> type;
	if (type == "Move") {
		pos= k;
	} else if (type == "Insert") {
		int id = pos;
		while (len) {
			getline(cin,s);
			for (int j = 0; j < s.length(); j ++) {
				if ((int)s[j] >= 32 && (int)s[j] <= 126) {
					w.insert(id,s[j]);
					id ++,len --;
				}
			}
		}
	} else if (type == "Delete") {
		w.erase(pos,len);
	} else if (type == "Get") {
		cout << w.substr(pos,len) << '\n';
	} else if (type == "Prev") {
		pos --;
	} else pos ++;

P4567 文本编辑器

这个题目和上面一题题意差不多,也就是多了一个有点阴间的翻转和很阴间的输入输出,谁家文本编辑器里面有换行符啊!!!谁还特判是不是换行符啊!!!$ CCF $ 请不要太自由了!!!

const int N = (1 << 22) + 5, inf = 0x3f3f3f3f;

char c[N],bc[N];
rope<char> w,h;
rope<char> tmp;

int T = fr();
string type,s;
int pos = 0;
for (int i = 1; i <= T; i ++) {
    if (type == "Move") {
        pos= k;
    } else if (type == "Insert") {
        int length = w.size();
        for (int i = 0; i <len; i ++) {
            c[i] = getchar();
            bc[len - i - 1] = c[i];
        }
        c[len] = bc[len] = '\0';
        w.insert(pos,c);
        h.insert(length - pos,bc);
    } else if (type == "Delete") {
        int length = w.size();
        w.erase(pos,len);
        h.erase(length - pos - len,len);
    } else if (type == "Rotate") {
        int length = w.size();
        tmp = w.substr(pos,len);
        w = w.substr(0,pos) + h.substr(length - pos - len,len) + w.substr(pos + len,length - pos - len);
        h = h.substr(0,length - pos - len) + tmp + h.substr(length - pos,pos);
    } else if (type == "Get") {
        putchar(w[pos]);
        if (w[pos] != 10) puts("");
    } else if (type == "Prev") {
        pos --;
    } else if (type == "Next") pos ++;
}

P3835 可持久化平衡树

int n;
rope<int> w[N];

for (u = 1; u <= n; u ++) {
    k = fr(),type = fr(), x = fr();
    w[u] = w[k];
    pos = lower_bound(w[u].begin(),w[u].end(),x) - w[u].begin();
    if (type == 1) {
        w[u].insert(pos,x);
    } else if (type == 2) {
        if (w[u][pos] != x) continue;
        w[u].erase(pos,1);
    } else if (type == 3) {
        fw(pos + 1);
        ch;
    } else if (type == 4) {
        fw(w[u][x - 1]);
        ch;
    } else if (type == 5) {
        if (!pos) puts("-2147483647");
        else fw(w[u][pos - 1]),ch;
    } else {
        pos = upper_bound(w[u].begin(),w[u].end(),x) - w[u].begin();
        if (pos > w[u].size()) puts("2147486347");
        else fw(w[u][pos]),ch;
    }
}

P6182 Time Travel S
这里就注意一下他回到的是第\(x\)个操作之前

rope<int> w[N];

for (u = 1; u <= n; u ++) {
    cin >> type;
    if (type == 'a') {
        w[u] = w[u - 1];
        w[u].push_back(x);
    } else if (type == 's') {
        w[u] = w[u - 1];
        w[u].pop_back();
    } else {
        w[u] = w[x - 1];
    }
    if (w[u].size() != 0)
        fw(w[u][w[u].size() - 1]),ch;
    else wj;
}

P6166 scrivener

rope<char> w[N];

while (n --) {
    if (s == "T") {
        w[u] = w[u - 1];
        w[u].push_back(c);
        u ++;
    } else if (s == "U") {
        w[u] = w[u - x - 1];
        u ++;
    } else {
        w[u] = w[u - 1];
        putchar(w[u][x]),ch;
    }
}

P3402 可持久化并查集
卡常失败了,有一个点死活卡不过去,罢了,九十五就九十五吧

rope<int> *h[N];
int f[N];

int find(int x) {
    int t = h[u] -> at(x);
    if (t != x)
        return find(t);
    return t;
}

for (int i = 1; i <= n; i ++)
    f[i] = i;
f[0] = 1;
h[0] = new rope<int>(f);

for (u = 1; u <= m; u ++) {
    if (type == 1) {
        h[u] = new rope<int>(*h[u - 1]);
        ha = find(a),hb = find(b);
        if (ha == hb) continue;
        h[u]->replace(ha,hb);
    } else if (type == 2) {
        h[u] = new rope<int>(*h[a]);
    } else {
        h[u] = new rope<int>(*h[u - 1]);
        ha = find(a),hb = find(b);
        if (ha == hb) puts("1");
        else puts("0");
    }
}
posted @ 2023-06-07 11:29  jingyu0929  阅读(22)  评论(0)    收藏  举报