求助,样例没过,悬赏2~3关注
查看原帖
求助,样例没过,悬赏2~3关注
518232
Sternenlicht楼主2023/5/7 18:35
#include <bits/stdc++.h>
namespace IO{
	#define LL long long
	inline LL read(){
		LL x=0,f=1;char c=getchar();
		for (;!isdigit(c);c=getchar())if (c=='-')f=-1;
		for (;isdigit(c);c=getchar())x=(x<<3)+(x<<1)+(c^48);
		return x*f;
	}
	inline void write(LL x,char c='\n'){
		if (x){
			if (x<0)x=-x,putchar('-');
			char a[30];short l;
			for (l=0;x;x/=10)a[l++]=x%10^48;
			for (l--;l>=0;l--)putchar(a[l]);
		}else putchar('0');putchar(c);
	}
}using namespace IO;
using namespace std;

const int N = 1e6+10;
const int INF = 2e9;
struct Splay{
	int son[2],siz,fa,val;
	int tag,rev,sum;
	int lsum,rsum,msum;
	void clear(){son[0]=son[1]=fa=rev=0,tag=INF;}
}tree[N];
int root,cnt,top,rec[N],a[N],id[N],n,m;
int recover(){if (!top)return ++cnt;return rec[top--];}
bool cmp(int now,int val){return tree[now].val<val;}
void updval(int now,int val){
	if (!now)return ;
	tree[now].tag=tree[now].val=val;
	tree[now].sum=val*tree[now].siz;
	tree[now].lsum=max(0,tree[now].sum);
	tree[now].rsum=max(0,tree[now].sum);
	tree[now].msum=max(val,tree[now].sum);
}
void updrev(int now){
	swap(tree[now].son[0],tree[now].son[1]);
	swap(tree[now].lsum,tree[now].rsum);
	tree[now].rev^=1;
}
void pushup(int now){
	Splay &ls=tree[tree[now].son[0]],&rs=tree[tree[now].son[1]];
	Splay &fa=tree[now];int val=tree[now].val;
	fa.sum=ls.sum+rs.sum+val;
	fa.siz=ls.siz+rs.siz+1;
	fa.msum=max(max(ls.msum,rs.msum),ls.rsum+rs.lsum+val);
	fa.lsum=max(ls.lsum,ls.sum+rs.lsum+val);
	fa.rsum=max(rs.rsum,rs.sum+ls.rsum+val);
}
void pushdown(int now){
	if (tree[now].tag!=INF)
		updval(tree[now].son[0],tree[now].tag),
		updval(tree[now].son[1],tree[now].tag),
		tree[now].tag=INF;
	if (tree[now].rev)
		updrev(tree[now].son[0]),
		updrev(tree[now].son[1]),
		tree[now].rev=0;
}
void rotate(int x){
	int f=tree[x].fa,g=tree[f].fa;
	int son=(tree[f].son[1]==x);
	tree[g].son[tree[g].son[1]==f]=x;
	tree[x].fa=g;
	tree[f].son[son]=tree[x].son[son^1];
	tree[tree[x].son[son^1]].fa=f;
	tree[x].son[son^1]=f;
	tree[f].fa=x;
	pushup(f);
	pushup(x);
}
void splaying(int x,int goal){
	while (tree[x].fa!=goal){
		int f=tree[x].fa,g=tree[f].fa;
		if (g!=goal)
			if (cmp(f,tree[x].val)!=cmp(g,tree[f].val))
				rotate(x);
			else
				rotate(f);
		rotate(x);
	}
	if (!goal)root=x;
}
void newnode(int now,int val){
	tree[now].lsum=tree[now].rsum=max(val,0);
	tree[now].msum=tree[now].sum=val;
	tree[now].tag=INF;
	tree[now].rev=0;
	tree[now].siz=1;
}
void build(int l,int r,int fa){
	int mid=(l+r)>>1,now=id[mid],pre=id[fa];
	if (l==r)newnode(now,a[l]);
	if (l<mid)build(l,mid-1,mid);
	if (mid<r)build(mid+1,r,mid);
	tree[now].val=a[mid];
	tree[now].fa=pre;
	tree[now].tag=INF;
	pushup(now);
	tree[pre].son[mid>=fa]=now;
}
int kth(int x){
	int now=root;
	while (1){
		pushdown(now);
		if (tree[tree[now].son[0]].siz>=x)now=tree[now].son[0];
		else if (tree[tree[now].son[0]].siz+1==x)return now;
		else x-=tree[tree[now].son[0]].siz+1,now=tree[now].son[1];
	}
}
void remove(int now){
	if (tree[now].son[0])remove(tree[now].son[0]);
	if (tree[now].son[1])remove(tree[now].son[1]);
	rec[++top]=now;
	tree[now].clear();
}
int split(int rnk,int len){
	int x=kth(rnk),y=kth(rnk+len+1);
	splaying(x,0);
	splaying(y,x);
	return tree[y].son[0];
}
void query(int rnk,int len){
	int now=split(rnk,len);
	write(tree[now].sum);
}
void update(int rnk,int len,int val){
	int now=split(rnk,len),y=tree[now].fa;
	updval(now,val);
	pushup(y);
	pushup(tree[y].fa);
}
void reverse(int rnk,int len){
	int now=split(rnk,len),y=tree[now].fa;
	if (tree[now].tag!=INF)return ;
	updrev(now);
	pushup(y);
	pushup(tree[y].fa);
}
void erase(int rnk,int len){
	int now=split(rnk,len),y=tree[now].fa;
	remove(now);
	tree[y].son[0]=0;
	pushup(y);
	pushup(tree[y].fa);
}
void insert(int rnk,int len){
	for (int i=1;i<=len;i++)a[i]=read();
	for (int i=1;i<=len;i++)id[i]=recover();
	build(1,len,0);
	int x=kth(rnk+1),y=kth(rnk+2);
	splaying(x,0);
	splaying(y,x);
	tree[id[(1+len)>>1]].fa=y;
	tree[y].son[0]=id[(1+len)>>1];
	pushup(y);
	pushup(x);
}
int main(){
	n=read(),m=read();
	tree[0].msum=a[1]=a[n+2]=-INF;
	for (int i=1;i<=n;i++)a[i+1]=read();
	for (int i=1;i<=n+2;i++)id[i]=i;
	build(1,n+2,0);
	root=(n+3)>>1,cnt=n+2;
	for (int i=1;i<=m;i++){
		string opt;cin>>opt;
		int x,y,len;
		if (opt!="MAX-SUM")x=read(),len=read();
		else write(tree[root].msum);
		if (opt=="INSERT")insert(x,len);
		if (opt=="DELETE")erase(x,len);
		if (opt=="MAKE_SAME")y=read(),update(x,len,y);
		if (opt=="REVERSE")reverse(x,len);
		if (opt=="GET-SUM")query(x,len);
	}
	return 0;
}
2023/5/7 18:35
加载中...