点击这里查看原题
Splay模板题,我WA了一次,TLE了两次
总结一下犯的错误就是两个:
- pushup里默认把mn[x]设为inf而非v[x]
- 数组开小,只开了1e5,应该至少开2e5的
/*
User:Small
Language:C++
Problem No.:1895
*/
#include<bits/stdc++.h>
#define ll long long
#define inf 999999999
using namespace std;
const int M=3e5+5;
int n,m,a[M],rt,cnt,id[M],ch[M][2],fa[M],mn[M],v[M],siz[M],lazy[M];
bool tag[M];
queue<int> q;
void pushup(int x){
int lson=ch[x][0],rson=ch[x][1];
siz[x]=1;
mn[x]=v[x];
if(lson){
siz[x]+=siz[lson];
mn[x]=min(mn[x],mn[lson]);
}
if(rson){
siz[x]+=siz[rson];
mn[x]=min(mn[x],mn[rson]);
}
}
void pushdown(int x){
int &lson=ch[x][0],&rson=ch[x][1];
if(lson){
lazy[lson]+=lazy[x];
mn[lson]+=lazy[x];
v[lson]+=lazy[x];
}
if(rson){
lazy[rson]+=lazy[x];
mn[rson]+=lazy[x];
v[rson]+=lazy[x];
}
lazy[x]=0;
if(tag[x]){
tag[lson]^=1;
tag[rson]^=1;
tag[x]^=1;
swap(lson,rson);
}
}
int get(int x){
return ch[fa[x]][1]==x;
}
void rotate(int x,int &k){
int y=fa[x],z=fa[y],side=get(x);
if(y==k) k=x;
else ch[z][ch[z][1]==y]=x;
ch[y][side]=ch[x][side^1];
fa[ch[y][side]]=y;
fa[y]=x;
ch[x][side^1]=y;
fa[x]=z;
pushup(y);
pushup(x);
}
void splay(int x,int &k){
while(x!=k){
if(fa[x]!=k) rotate((get(x)==get(fa[x])?fa[x]:x),k);
rotate(x,k);
}
}
int findx(int x){
int now=rt;
while(1){
if(tag[now]||lazy[now]) pushdown(now);
if(siz[ch[now][0]]>=x) now=ch[now][0];
else{
x-=siz[ch[now][0]]+1;
if(x<=0) return now;
now=ch[now][1];
}
}
}
int spilt(int l,int r){
int x=findx(l),y=findx(r+2);
splay(x,rt);splay(y,ch[x][1]);
return y;
}
void build(int l,int r,int f){
if(l>r) return;
int mid=l+r>>1,now=id[mid],last=id[f];
v[now]=a[mid];
if(l==r){
siz[now]=1;
mn[now]=a[mid];
}
else{
build(l,mid-1,mid);
build(mid+1,r,mid);
pushup(now);
}
fa[now]=last;
ch[last][mid>f]=now;
}
void add(int l,int r,int k){
int x=spilt(l,r),y=ch[x][0];
lazy[y]+=k;
mn[y]+=k;
v[y]+=k;
pushup(x);
pushup(fa[x]);
}
void ins(int x,int p){
int y=spilt(x+1,x);
if(!q.empty()){
id[1]=q.front();
q.pop();
}
else id[1]=++cnt;
siz[id[1]]=1;
v[id[1]]=mn[id[1]]=p;
fa[id[1]]=y;
ch[y][0]=id[1];
pushup(y);
pushup(fa[y]);
}
void del(int x){
int y=spilt(x,x),z=ch[y][0];
siz[z]=lazy[z]=tag[z]=v[z]=mn[z]=ch[z][0]=ch[z][1]=fa[z]=0;
q.push(z);
ch[y][0]=0;
pushup(y);
pushup(fa[y]);
}
int getmin(int l,int r){
int y=spilt(l,r);
return mn[ch[y][0]];
}
void rev(int l,int r){
int y=spilt(l,r);
tag[ch[y][0]]^=1;
}
void revo(int l,int r,int t){
t%=(r-l+1);
if(t==0) return;
int y=spilt(r-t+1,r),x=ch[y][0];
fa[x]=ch[y][0]=0;
pushup(y);
pushup(fa[y]);
y=spilt(l,l-1);
ch[y][0]=x;
fa[x]=y;
pushup(y);
pushup(fa[y]);
}
int main(){
freopen("data.in","r",stdin);//
scanf("%d",&n);
a[1]=a[n+2]=inf;
for(int i=2;i<=n+1;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n+2;i++) id[i]=i;
rt=(n+3)>>1,cnt=n+2;
build(1,n+2,0);
scanf("%d",&m);
while(m--){
char op[15];
int x,y,p;
scanf("%s%d",op,&x);
switch(op[0]){
case 'D':n--;del(x);break;
case 'I':{
scanf("%d",&p);
n++;
ins(x,p);
break;
}
case 'A':{
scanf("%d%d",&y,&p);
if(x>y) swap(x,y);
add(x,y,p);
break;
}
case 'M':{
scanf("%d",&y);
printf("%d\n",getmin(x,y));
break;
}
case 'R':{
if(op[3]=='E'){
scanf("%d",&y);
if(x==y) continue;
if(x>y) swap(x,y);
rev(x,y);
}
else{
scanf("%d%d",&y,&p);
if(x>y) swap(x,y);
revo(x,y,p);
}
break;
}
}
}
return 0;
}