可持久化线段树
福利板子题
可持久化数据结构的坑就开始填一个吧。。
哈哈哈A啦,有几个傻逼错误如下:
1.读入优化写错 以后我tm再也不用了
2.建树时要判断节点是否建过了,不判断的脑残飘过
3.修改操作时要引用,还好我拿眼睛看出来了,不过也是个错误吧
4.不用相信题目的数据范围。
有了这个经验,下一个题就是区间第k大了吧。
代码还是很有意义的,贴上去吧。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<vector>
using namespace std;
const int maxn = 3000000;
const int maxm = 1000000;
const int INF = ~0U>>1;
struct Node{
int M;
int lch,rch;
Node(){M = -INF;lch = 0,rch = 0;}
};
Node tree[maxn];
Node root[maxm];
int snode;int sroot = 1;
void build(Node& o,int L,int R,int x,int v)
{
if(L == R){o.M = v;return;}
int M = L+(R-L)/2;
if(x <= M){if(tree[o.lch].M == -INF) o.lch = ++snode;build(tree[o.lch],L,M,x,v);}
if(x > M) {if(tree[o.rch].M == -INF) o.rch = ++snode;build(tree[o.rch],M+1,R,x,v);}
o.M = max(tree[o.lch].M,tree[o.rch].M);
}
void update(Node& o,Node& k ,int L,int R,int x,int v)
{
if(L == R){k.M = v;return;}
int M = L+(R-L)/2;
if(x <= M){k.rch = o.rch;k.lch = ++snode;update(tree[o.lch],tree[k.lch],L,M,x,v);}
if(x > M) {k.lch = o.lch;k.rch = ++snode;update(tree[o.rch],tree[k.rch],M+1,R,x,v);}
k.M = max(tree[k.lch].M,tree[k.rch].M);
}
int query(Node& o,int L,int R,int q1,int q2)
{
if(q1 <= L&&R <= q2){return o.M;}
int M = L+(R-L)/2;
int ans = -INF;
if(q1 <= M) ans = max(ans,query(tree[o.lch],L,M,q1,q2));
if(q2 > M) ans = max(ans,query(tree[o.rch],M+1,R,q1,q2));
return ans ;
}
int main()
{
freopen("longterm_segtree.in","r",stdin);
freopen("longterm_segtree.out","w",stdout);
int n,m;
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i++){
int v ;scanf("%d",&v);
build(root[1],1,n,i,v);
}
while(m--){
int op,k,a,b;
scanf("%d%d%d%d",&op,&k,&a,&b);
if(op == 0){if(a > b) swap(a,b);printf("%d\n",query(root[k],1,n,a,b));}
else update(root[k],root[++sroot],1,n,a,b);
}
return 0;
}
代码能力还是不够啊,没能一次ac。哎。

浙公网安备 33010602011771号