社区讨论
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 条回复,欢迎继续交流。
正在加载回复...