求助一道平衡树题
  • 板块学术版
  • 楼主Glassy_Sky
  • 当前回复2
  • 已保存回复2
  • 发布时间2023/5/25 20:35
  • 上次更新2023/10/23 14:46:52
查看原帖
求助一道平衡树题
157884
Glassy_Sky楼主2023/5/25 20:35

题目:

1

样例输入:

9 8 
2 -6 3 5 1 -5 -3 6 3 
GET-SUM 5 4
MAX-SUM
INSERT 8 3 -5 7 2
DELETE 12 1
MAKE-SAME 3 3 2
REVERSE 3 6
GET-SUM 5 4
MAX-SUM


输出:

-1
10
1
10

我用的是非旋平衡树(FHQ),

然而我这里在修改过数列之后,

维护的 sumsum 值和 maxxmaxx 值都出问题了(即 区间和 和 最大子区间和 的值)。

有没有大佬帮帮忙。

  • 代码:
#include<bits/stdc++.h>
using namespace std;

const int maxn=5e5+5;

int n,m,idx=0,root,dl,dr;
struct FHQ {
	int key,val,ls,rs,siz,flag;
	int sum,lsum,rsum,maxx;
	bool tag;
}tr[maxn];

int add(int key) {
	tr[++idx].key=key;
	tr[idx].val=rand();
	tr[idx].siz=1;
	tr[idx].sum=key;
	tr[idx].flag=-1000;
	if(key>=0) {
		tr[idx].lsum=key;
		tr[idx].rsum=key;
		tr[idx].maxx=key;
	}
	return idx;
}
inline void pushup(int spot) {
	tr[spot].siz=tr[tr[spot].ls].siz+tr[tr[spot].rs].siz+1;
	tr[spot].sum=tr[tr[spot].ls].sum+tr[tr[spot].rs].sum+tr[spot].key;
	tr[spot].lsum=max(tr[tr[spot].ls].lsum,tr[tr[spot].ls].sum+tr[tr[spot].rs].lsum+tr[spot].key);
	tr[spot].rsum=max(tr[tr[spot].rs].rsum,tr[tr[spot].rs].sum+tr[tr[spot].ls].rsum+tr[spot].key);
	tr[spot].maxx=max(tr[tr[spot].ls].maxx,tr[tr[spot].rs].maxx);
	tr[spot].maxx=max(tr[tr[spot].ls].rsum+tr[tr[spot].rs].lsum+tr[spot].key,tr[spot].maxx);
}
inline void pushdown(int spot) {
	if(tr[spot].flag!=-1000) {
		tr[tr[spot].ls].key=tr[spot].flag;
		tr[tr[spot].rs].key=tr[spot].flag;
		tr[tr[spot].ls].flag=tr[spot].flag;
		tr[tr[spot].rs].flag=tr[spot].flag;
		tr[spot].flag=-1000;
	}
	if(!tr[spot].tag) return ;
	tr[tr[spot].ls].tag^=1;
	tr[tr[spot].rs].tag^=1;
	swap(tr[spot].ls,tr[spot].rs);
	tr[spot].tag=0;
}
void split(int spot,int k,int& l,int& r) {
	if(!spot) {
		l=r=0;
		return ;
	}
	pushdown(spot);
	int cnt=tr[tr[spot].ls].siz+1;
	if(cnt<=k) {
		l=spot;
		split(tr[spot].rs,k-cnt,tr[l].rs,r);
	}
	else {
		r=spot;
		split(tr[spot].ls,k,l,tr[r].ls);
	}
	pushup(spot);
}
int merge(int l,int r) {
	if(!l||!r) return l|r;
	pushdown(l);
	pushdown(r);
	if(tr[l].val<=tr[r].val) {
		tr[l].rs=merge(tr[l].rs,r);
		pushup(l);
		return l;
	}
	else {
		tr[r].ls=merge(l,tr[r].ls);
		pushup(r);
		return r;
	}
}
void rever(int L,int len) {
	int t1,t2,t3,t4;
	split(root,L-1,t1,t2);
	split(t2,len,t3,t4);
	tr[t3].tag^=1;
	t2=merge(t3,t4);
	root=merge(t1,t2);
}
void update(int pos,int len,int k) {
	split(root,pos-1,dl,dr);
	int t1,t2;
	split(dr,len,t1,t2);
	tr[t1].key=k;
	tr[t1].flag=k;
	dr=merge(t1,t2);
	root=merge(dl,dr);
}
void print(int spot) {
	if(!spot) return ;
//	pushdown(spot);
//	pushup(spot);
	print(tr[spot].ls);
	printf("%d ",tr[spot].key);
	print(tr[spot].rs);
}
int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) {
		int a;
		scanf("%d",&a);
		root=merge(root,add(a));
	}
	while(m--) {
		string opt;
		cin>>opt;
		if(opt=="INSERT") {
			int pos,tot;
			scanf("%d%d",&pos,&tot);
			split(root,pos,dl,dr);
			while(tot--) {
				int a;
				scanf("%d",&a);
				dl=merge(dl,add(a));
			}
			root=merge(dl,dr);
		}
		else if(opt=="DELETE") {
			int pos,tot;
			scanf("%d%d",&pos,&tot);
			split(root,pos-1,dl,dr);
			int t1,t2;
			split(dr,tot,t1,t2);
			root=merge(dl,t2);
		}
		else if(opt=="MAKE-SAME") {
			int pos,tot,c;
			scanf("%d%d%d",&pos,&tot,&c);
			update(pos,tot,c);
		}
		else if(opt=="REVERSE") {
			int pos,tot;
			scanf("%d%d",&pos,&tot);
			rever(pos,tot);
		}
		else if(opt=="GET-SUM") {
			int pos,tot;
			scanf("%d%d",&pos,&tot);
			split(root,pos-1,dl,dr);
			int t1,t2;
			split(dr,tot,t1,t2);
			
//			print(t1);
//			cout<<endl;
			
			printf("%d\n",tr[t1].sum);
			dr=merge(t1,t2);
			root=merge(dl,dr);
		}
		else if(opt=="MAX-SUM") {
//			print(root);
//			cout<<endl;
			printf("%d\n",tr[root].maxx);
		}
	}
	return 0;
}
//2 -6 6 -3 -5 2 2 2 -5 7 2
2023/5/25 20:35
加载中...