树套树 - AcWing 2488
树套树 - AcWing 2488
树套树是一个非常暴力的数据结构。线段树维护区间,每个线段树的结点分别又是一棵平衡树。这样就可以解决任意区间的动态查询前驱问题。
#include <bits/stdc++.h>
using namespace std;
const int N = 5e4+10,INF = 0x3fffffff;
int n,m,op,L,R,X;
int arr[N];
multiset<int> tree[N<<2];
void build(int l,int r,int rt){
tree[rt].insert(-INF); // 哨兵防越界
for(int i = l; i <= r; ++i){
tree[rt].insert(arr[i]);
}
if(l==r)return;
int mid = l+r>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
}
void modify(int l,int r,int rt,int pos,int v){
tree[rt].erase(tree[rt].find(arr[pos]));
tree[rt].insert(v);
if(l==r){
arr[pos] = v;
}else{
int mid = l+r>>1;
if(pos <= mid){
modify(l,mid,rt<<1,pos,v);
}else{
modify(mid+1,r,rt<<1|1,pos,v);
}
}
}
int query(int l,int r,int rt,int ql,int qr,int x){
if(ql <= l && qr >= r){
return *--tree[rt].lower_bound(x);
}else{
int mid = l+r>>1;
int ans = -INF;
if(ql <= mid){
ans = max(ans,query(l,mid,rt<<1,ql,qr,x));
}
if(qr > mid){
ans = max(ans,query(mid+1,r,rt<<1|1,ql,qr,x));
}
return ans;
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; ++i){
scanf("%d",&arr[i]);
}
build(1,n,1);
while(m--){
scanf("%d",&op);
if(op == 1){
scanf("%d%d",&L,&X);
modify(1,n,1,L,X);
}else{
scanf("%d%d%d",&L,&R,&X);
printf("%d\n",query(1,n,1,L,R,X));
}
}
// system("pause");
return 0;
}
---- suffer now and live the rest of your life as a champion ----