类似线段树分裂20pts求调
查看原帖
类似线段树分裂20pts求调
482452
Bamboo_Day楼主2023/11/13 16:25

RT
思路是把线段树分成两棵树然后查找,但是不知道为什么错了

#include <bits/stdc++.h>
const int N = 1e6+10;
//#define int long long
using namespace std;
struct Node{
	int l,r,ma,mi,siz;
}tr[N*40];
int tot;
#define siz(pos) tr[pos].siz
#define ma(pos) tr[pos].ma
#define mi(pos) tr[pos].mi
#define ls(pos) tr[pos].l
#define rs(pos) tr[pos].r
int a[N];

void push_up(int pos){
	if(!ls(pos)&&!rs(pos)) return;
	siz(pos) = siz(ls(pos)) + siz(rs(pos));
	ma(pos) = max((ls(pos) ? ma(ls(pos)) : -1e9),(rs(pos) ? ma(rs(pos)) : -1e9));	
	mi(pos) = min((ls(pos) ? mi(ls(pos)) : 1e9),(rs(pos) ? mi(rs(pos)) : 1e9));	
//	ma(pos) = max(ma(ls(pos)),ma(rs(pos)));
//	mi(pos) = min(mi(ls(pos)),mi(mi(pos)));
}
void build(int &pos, int l, int r){
	pos = ++tot;
	if(l == r){
		siz(pos) = 1;
		ma(pos) = a[l];
		mi(pos) = a[l];
		return;
	}	
	int mid = (l+r) >> 1;
	build(ls(pos),l,mid);
	build(rs(pos),mid+1,r);
	push_up(pos); 
} 
void del(int &pos,int l, int r,int x){
	if(l == r){
		pos = 0;
		return;
	}
	int mid = (l+r)>>1;
	if(x <= siz(ls(pos))) del(ls(pos),l,mid,x);
	else del(rs(pos),mid+1,r,x-siz(ls(pos)));
	push_up(pos);
}

void split(int rt,int &x, int &y, int k){//把以rt为根的树分裂成 x 和 y 两棵树 ,一颗大小为 k 
	if(!rt) return;
	y = ++tot;
	x = ++tot;
	if(k == siz(rt)){
		tr[x] = tr[rt];
		return;
	}
//	cout << rt << " " << v << " 1111 " << endl;
	if(k > siz(ls(rt))){ 
		ls(x) = ls(rt);
		split(rs(rt),rs(x),y,k-siz(ls(rt)));
	}else if(k == siz(ls(rt))){
		tr[x] = tr[ls(rt)];
		tr[y] = tr[rs(rt)];
	}else{
		rs(y) = rs(rt);
		split(ls(rt),x,ls(y),k);
	}
	push_up(x);
	push_up(y);
} 
void print(int pos){
	if(!ls(pos) && !rs(pos)){
		cout << ma(pos) << "x" << mi(pos) << " ";
		return;
	}
	if(ls(pos)) print(ls(pos));
	if(rs(pos)) print(rs(pos));
}
int rt;
int n,m;
void query(int l, int r){
	int tmp = tot;
	int x = 0,y = 0,z = 0,w = 0;
	split(rt,x,y,r);
//	cout << siz(y) << endl;
//	print(x);
//	print(y,r+1,n);
	split(x,w,z,l-1);
//	print(x,1,n);
//	cout << siz(x) << " xxx " << siz(y) << endl; 
	cout << mi(z) << " " << ma(z) << endl;
	for(int i = tmp+1; i <= tot; i++) tr[i] = {0,0,0,0,0};
	tot = tmp;
}

int main(){
//	mi(0) = 1e9;
//	ma(0) = -1e9;
	cin >> n >> m;
	for(int i = 1; i <= n; i++) cin >> a[i];
	build(rt,1,n);
	while(m--){
//	print(rt);
		int op;
		cin >> op;
		if(op == 1){
			int k;
			cin >> k;
			del(rt,1,n,k);
		}else{
			int x,y;
			cin >> x >> y;
			query(x,y);
		}
	}	
	return 0;
}
2023/11/13 16:25
加载中...