ACM入门之【可持续化数组(Rope)】

一个黑科技,有时候可以用来偷鸡。万一过了呢?

rope(可持续化平衡树)

  • 需要的头文件#include <ext/rope>
  • 命名空间声明:using namespace __gnu_cxx;
  • 常用的函数:
    • rope<int> a;
    • a.push_back(x) // 在尾部插入
    • a.append(x) //在尾部插入
    • a.pop_back(x) // 删除最后一个元素
    • a.size() // 返回长度
    • a.insert(int pos, x) // 在pos插入x
    • a.erase(int pos, int sum) // 在pos删除sum个元素
    • a.replace(int pos, x) // 将pos替换为x
    • a.substr(int pos, int sum) // 在pos处截取sum个元素
    • a.at(x) a[x] //访问第x个元素

时间复杂度:O(nsqrt(n))
空间复杂度: 玄学
它的复制很快O(1)
在这里插入图片描述
https://www.luogu.com.cn/problem/P3919
这一道题,用vector暴力只能拿40分,用rope暴力能拿64分。

#include<bits/stdc++.h>
#include<ext/rope>
using namespace std;
using namespace __gnu_cxx;
const int N=1e6+10;
rope<int> S[N];
int n,m;
int main()
{
    
    
    scanf("%d%d",&n,&m);
    S[0].append(0);
    for(int i=1;i<=n;i++)
    {
    
    
    	int x; scanf("%d",&x); 
        S[0].append(x);
    }
    for(int i=1;i<=m;i++)
	{
    
    
        int v,k,a,b; scanf("%d%d",&v,&k);
        S[i]=S[v];//从指定版本生成新版本(只换根)
        if(k==1) 
		{
    
    
            scanf("%d%d",&a,&b);
            S[i].replace(a,b);
        } 
		else 
		{
    
    
            scanf("%d",&a);
            printf("%d\n",S[i].at(a));
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_46527915/article/details/124833886