神秘线段树问题求助!!
查看原帖
神秘线段树问题求助!!
175011
rfsfreffr楼主2022/8/27 17:18

我想偷懒,直接 每个节点分成俩个部分维护(*(-1)和不乘(-1)) , 但是感觉好像又有问题,当然是萎了。

#include <bits/stdc++.h>
#define ls(p) 2*p
#define rs(p) 2*p+1
using namespace std;

const int N=1e5+5;

struct tree {
	int maxn[2];
	int lmax[2];
	int rmax[2];
	int sum[2];
	int tag;
	int L[2];
	int R[2];
	int Lst[2];
	int Rst[2];
	tree() {
		tag=0;
		maxn[0]=lmax[0]=rmax[0]=-2e9;
		maxn[1]=lmax[1]=rmax[1]=-2e9;
		sum[0]=sum[1]=0;
		Lst[0]=Lst[1]=Rst[0]=Rst[1]=0;
	}
};

struct oi {
	int l,r;
};

tree T[N*4];
int n,q;
int a[N];
stack<oi> s;

tree merge(tree A,tree B) {
	tree C;
	int id1=A.tag,id2=B.tag;
	for(int i=0; i<=1; i++) {
		C.sum[i]=A.sum[id1]+B.sum[id2];
		C.lmax[i]=A.lmax[id1],C.Lst[i]=A.Lst[id1];
		if(A.sum[id1]+B.lmax[id2]>C.lmax[i]) C.lmax[i]=A.sum[id1]+B.lmax[id2],C.Lst[i]=B.Lst[id2];
		C.rmax[i]=B.rmax[id2],C.Rst[i]=B.Rst[id2];
		if(B.sum[id2]+A.rmax[id1]>C.rmax[i]) C.rmax[i]=B.sum[id2]+A.rmax[id1],C.Rst[i]=A.Rst[id1];
		if(A.maxn[id1]>C.maxn[i]) C.maxn[i]=A.maxn[id1],C.L[i]=A.L[id1],C.R[i]=A.R[id1];
		if(B.maxn[id2]>C.maxn[i]) C.maxn[i]=B.maxn[id2],C.L[i]=B.L[id2],C.R[i]=B.R[id2];
		if(A.rmax[id1]+B.lmax[id2]>C.maxn[i]) C.maxn[i]=A.rmax[id1]+B.lmax[id2],C.L[i]=A.Rst[id1],C.R[i]=B.Lst[id2];
		id1^=1,id2^=1;
	}
	return C;
}

void change(int p,int l,int x) {
	int id=T[p].tag;
	for(int i=0; i<=1; i++) {
		T[p].Lst[id]=T[p].Rst[id]=T[p].L[id]=T[p].R[id]=l;
		T[p].sum[id]=T[p].maxn[id]=T[p].lmax[id]=T[p].rmax[id]=x;
		id^=1,x=-x;
	}
}

void build(int p,int l,int r) {
	if(l==r) {
		change(p,l,a[l]);
		return ;
	}
	int mid=(l+r)>>1;
	build(ls(p),l,mid);
	build(rs(p),mid+1,r);
	T[p]=merge(T[ls(p)],T[rs(p)]);
}

void update(int p,int l,int r,int x,int y) {
	if(l==r) {
		change(p,l,y);
		return ;
	}
	int mid=(l+r)>>1;
	T[ls(p)].tag^=T[p].tag,T[rs(p)].tag^=T[p].tag,T[p].tag=0;
	if(x<=mid) update(ls(p),l,mid,x,y);
	if(x>mid)  update(rs(p),mid+1,r,x,y);
	T[p]=merge(T[ls(p)],T[rs(p)]);
}

void update2(int p,int l,int r,int L,int R) {
	int mid=(l+r)>>1;
	if(L<=l&&r<=R) {
		T[p].tag^=1;
		return ;
	}
	T[ls(p)].tag^=T[p].tag,T[rs(p)].tag^=T[p].tag,T[p].tag=0;
	if(L<=mid) update2(ls(p),l,mid,L,R);
	if(R>mid)  update2(rs(p),mid+1,r,L,R);
	T[p]=merge(T[ls(p)],T[rs(p)]);
}

tree query(int p,int l,int r,int L,int R) {
	if(L<=l&&r<=R) return T[p];
	int mid=(l+r)>>1;
	T[ls(p)].tag^=T[p].tag,T[rs(p)].tag^=T[p].tag,T[p].tag=0;
	if(L>mid)  return query(rs(p),mid+1,r,L,R);
	if(R<=mid) return query(ls(p),l,mid,L,R);
	return merge(query(ls(p),l,mid,L,R),query(rs(p),mid+1,r,L,R));
}

int main() {
	cin>>n;
	int tot=0;
	for(int i=1; i<=n; i++)
		scanf("%d",&a[i]),tot+=a[i];
	cin>>q;
	build(1,1,n);
	while(q--) {
		int op;
		scanf("%d",&op);
		if(op==0) {
			int x,y;
			scanf("%d%d",&x,&y);
			update(1,1,n,x,y);
		}
		if(op==1) {
			int l,r,k;
			scanf("%d%d%d",&l,&r,&k);
			int ans=0;
			for(int i=1; i<=k; i++) {
				tree tmp=query(1,1,n,l,r);
				int p=tmp.tag;
				if(tmp.maxn[p]<0) break;
				ans+=tmp.maxn[p];
				int L_=tmp.L[p];
				int R_=tmp.R[p];
				update2(1,1,n,L_,R_);
				s.push({L_,R_});
			}
			while(!s.empty()) {
				oi tmp=s.top();
				update2(1,1,n,tmp.l,tmp.r);
				s.pop();
			}
			printf("%d\n",ans);
		}
	}
	return 0;
}
2022/8/27 17:18
加载中...