社区讨论

Splay,样例都过不了

P2042[NOI2005] 维护数列参与者 7已保存回复 11

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
11 条
当前快照
1 份
快照标识符
@mi7pvi1p
此快照首次捕获于
2025/11/21 01:40
4 个月前
此快照最后确认于
2025/11/21 01:54
4 个月前
查看原帖
CPP
#include<iostream>
#include<queue>
#include<cstdio>
using namespace std;
const int N=1e6+5,inf=1000000000;
int ch[N][2],par[N],a[N],s[N],v[N];
int sum[N],mx[N],lx[N],rx[N],id[N];
bool ma[N],mr[N];
int n,m,root,tot;
queue<int> q;
void push(int x){
	int l=ch[x][0],r=ch[x][1];
	s[x]=s[l]+s[r]+1;
	sum[x]=sum[l]+sum[r]+v[x];
	mx[x]=max(mx[l],mx[r]);
	mx[x]=max(mx[x],rx[l]+v[x]+lx[r]);
	lx[x]=max(lx[x],sum[l]+v[x]+lx[r]);
	rx[x]=max(rx[x],sum[r]+v[x]+rx[l]);
}
void pushdown(int x){
	int l=ch[x][0],r=ch[x][1];
	if(ma[x]){
		mr[x]=ma[x]=0;
		if(l)ma[l]=1,v[l]=v[x],sum[l]=v[x]*s[l];
		if(r)ma[r]=1,v[l]=v[r],sum[r]=v[x]*s[r];
		if(v[x]>=0){
			if(l)lx[l]=rx[l]=mx[l]=sum[l];
			if(r)lx[r]=rx[r]=mx[r]=sum[r];
		}
		else{
			if(l)lx[l]=rx[l]=0,mx[l]=v[x];
			if(r)lx[r]=rx[r]=0,mx[r]=v[x];
		}
	}
	if(mr[x]){
		mr[x]^=1;mx[l]^=1;mx[r]^=1;
		swap(lx[l],rx[l]);swap(lx[r],rx[r]);
		swap(ch[l][0],ch[l][1]);swap(ch[r][0],ch[r][1]);
	}
}
bool chk(int x){
	return ch[par[x]][1]==x;
}
void turn(int x){
	int y=par[x],z=par[y],k=chk(x),t=ch[x][k^1];
	ch[y][k]=t;par[t]=y;
	ch[z][chk(y)]=x;par[x]=z;
	ch[x][k^1]=y;par[y]=x;
	push(y);push(x);
}
void splay(int x,int tar=0){
    while(par[x]!=tar){
        int y=par[x],z=par[y];
        if(z!=tar){
            if(chk(x)==chk(y))turn(y);
            else turn(x);
        }
        turn(x);
    }
    if(!tar)root=x;
}
int find(int x,int k){
    pushdown(x);
    int l=ch[x][0],r=ch[x][1];
    if(s[l]+1==k)return x;
    if(s[l]>=k)return find(l,k);
    return find(r,k-s[l]-1);
}
void rec(int x){
	if(!x)return;
	int l=ch[x][0],r=ch[x][1];
	rec(l);rec(r);q.push(x);
	par[x]=ch[x][0]=ch[x][1]=0;
	ma[x]=mr[x]=0;
}
int split(int x,int k){
	int l=find(root,x),r=find(root,x+k+1);
	splay(l);splay(r,l);
	return ch[r][0];
}
void found(int x,int k){
	int t=split(x,k);
	printf("%d\n",sum[t]);
}
void cop(int x,int k,int val){
	int t=split(x,k),y=par[t];
	v[t]=val;ma[t]=1;sum[t]=val*s[t];
	if(val>=0)lx[t]=rx[t]=mx[t]=sum[t];
	else lx[t]=rx[t]=0,mx[t]=val;
	push(y);push(par[y]);
}
void rev(int x,int k){
	int t=split(x,k),y=par[t];
	if(!ma[t]){
		mr[t]^=1;
		swap(ch[t][0],ch[t][1]);
		swap(lx[t],rx[t]);
		push(y);push(par[y]);
	}
}
void rem(int x,int k){
	int t=split(x,k),y=par[t];
	rec(t);ch[y][0]=0;
	push(y);push(par[y]);
}
void build(int l,int r,int x){
	if(l>r)return;
	int mid=(l+r)>>1,now=id[mid],last=id[x];
	if(l==r){
		sum[now]=a[l];s[now]=1;
		ma[now]=mr[now]=0;
		if(a[l]>=0)lx[now]=rx[now]=mx[now]=a[l];
		else lx[now]=rx[now]=0,mx[now]=a[l];
	}
	else build(l,mid-1,mid),build(mid+1,r,mid);
	v[now]=a[mid];par[now]=last;push(now);
	ch[last][mid>=x]=now;
}
void ins(int x,int k){
	for(int i=1;i<=k;i++)scanf("%d",&a[i]);
	for(int i=1;i<=k;i++){
		if(!q.empty())id[i]=q.front(),q.pop();
		else id[i]=++tot;
	}
	build(1,k,0);
	int t=id[(k+1)>>1];
	int l=find(root,x+1),r=find(root,x+2);
	splay(l);splay(r,l);
	par[t]=r;ch[r][0]=t;
	push(r);push(l);
}
int main(){
	scanf("%d%d",&n,&m);
	mx[0]=a[1]=a[n+2]=-inf;
	for(int i=1;i<=n;i++)scanf("%d",&a[i+1]);
	for(int i=1;i<=n+2;i++)id[i]=i;
	build(1,n+2,0);
	root=(n+3)>>1;
	tot=n+2;
	char ch[10];
	int x,y,z;
	while(m--){
		scanf("%s",ch);
		if(ch[0]!='M'||ch[2]!='X')scanf("%d%d",&x,&y);
		if(ch[0]=='I')ins(x,y);
		if(ch[0]=='D')rem(x,y);
		if(ch[0]=='M'){
			if(ch[2]=='X')printf("%d\n",mx[root]);
			else scanf("%d",&z),cop(x,y,z);
		}
		if(ch[0]=='R')rev(x,y);
		if(ch[0]=='G')found(x,y);
	}
}

回复

11 条回复,欢迎继续交流。

正在加载回复...