BZOJ3678 wangxz与OJ
由于题面包含不良信息,因此这里只放传送门。
题目大意:
维护一个序列,支持:
1、区间删除
2、在一个位置插入一段递增或递减的连续的数
3、单点查询
$splay$拆点,一个节点表示段连续的区间,必要时将一个点分裂成两个点。
空间一定是线性的,思维含量并不高,但是细节一堆。
很裸吧......
你写吧......
我们强无敌的$wxjor$巨佬以$6KB$代码$47pt$收场。
俗话说得好
有些人还活着,但它们的代码已经调不出来了。
有些人已经死了,但它们的代码还没有调出来。
只要写不死,就往死里写。
$Orz$模拟赛里$Ac$的神爷们
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define M 600020
#define ls c[x][0]
#define rs c[x][1]
using namespace std;
int read(){
int nm=0,fh=1; char cw=getchar();
for(;!isdigit(cw);cw=getchar()) if(cw=='-') fh=-fh;
for(;isdigit(cw);cw=getchar()) nm=nm*10+(cw-'0');
return nm*fh;
}
int tpe,n,m,T,c[M][2],cnt,rt,fa[M],L[M],R[M],sum[M],X,Y;
void pushup(int x){sum[x]=sum[ls]+sum[rs]+abs(R[x]-L[x])+1;}
void rotate(int x){
int tp=fa[x],dtp=fa[fa[x]],ms,ds;
if(dtp&&c[dtp][0]==tp) c[dtp][0]=x; else if(dtp) c[dtp][1]=x;
if(c[tp][0]==x) ms=0,ds=1;else ds=0,ms=1;
fa[x]=dtp,fa[tp]=x,fa[c[x][ds]]=tp;
c[tp][ms]=c[x][ds],c[x][ds]=tp,pushup(tp),pushup(x);
}
void splay(int x,int tar){
while(fa[x]!=tar){
int tp=fa[x];
if(fa[tp]==tar){rotate(x);break;}
if(c[c[fa[tp]][0]][0]==x) rotate(tp);
else if(c[c[fa[tp]][1]][1]==x) rotate(tp);
else rotate(x);
}
if(!tar) rt=x;
}
int fd(int x,int rk){
if(sum[ls]>=rk) return fd(ls,rk);
if(sum[x]-sum[rs]>=rk) return x;
return fd(rs,rk-sum[x]+sum[rs]);
}
int mn(int x){for(;ls;x=ls); return x;}
int query(int pos){
int x=fd(rt,pos),dt,rm; splay(x,0);
dt=(R[x]>=L[x]?1:-1),rm=pos-sum[ls]-1;
return L[x]+rm*dt;
}
void ins(int pos,int t1,int t2){
int x=++cnt,u; L[x]=t1,R[x]=t2,pushup(x);
if(!rt){rt=x; return;}
if(!pos){rs=rt,fa[rt]=x,rt=x,pushup(x);return;}
int now=fd(rt,pos); splay(now,0);
if(sum[now]-sum[c[now][1]]==pos){
if((u=mn(c[now][1]))==0) c[now][1]=x,fa[x]=now,pushup(now);
else splay(u,now),c[u][0]=x,fa[x]=u,pushup(u),pushup(now);
}
else{
int dt=(R[now]>=L[now]?1:-1),rm=pos-sum[c[now][0]];
cnt++,R[cnt]=R[now],L[cnt]=dt*rm+L[now],R[now]=L[cnt]-dt;
c[cnt][1]=c[now][1],c[now][1]=0,pushup(now),pushup(cnt),fa[c[cnt][1]]=cnt;
ls=now,rs=cnt,fa[now]=fa[cnt]=x,rt=x,fa[0]=0,pushup(x);
}
}
void del(int t1,int t2){
int x=fd(rt,t1),y=fd(rt,t2),u,dt; splay(x,0);
t1-=sum[ls],splay(y,0),t2-=sum[c[y][0]];
if(x!=y){
splay(x,y),rs=0,pushup(x),pushup(y);
if(t1>1) dt=(R[x]>=L[x]?1:-1),R[x]=L[x]+dt*(t1-2),pushup(x),pushup(y);
else fa[ls]=y,fa[0]=0,c[y][0]=ls,pushup(y); x=y;
if(t2<abs(R[x]-L[x])+1) dt=(R[x]>=L[x]?1:-1),L[x]+=dt*t2,pushup(x);
else if((y=mn(rs))==0) rt=ls,fa[ls]=0;
else splay(y,x),rt=y,c[y][0]=ls,fa[ls]=y,fa[y]=0,pushup(y);
}
else{
dt=(R[x]>=L[x]?1:-1);
if(t2-t1==abs(R[x]-L[x])){
if((u=mn(rs))==0) rt=ls,fa[ls]=0;
else splay(u,x),c[u][0]=ls,fa[ls]=u,fa[u]=0,rt=u,pushup(u);
}
else if(t1==1) L[x]+=(t2-t1+1)*dt,pushup(x);
else if(t2==abs(R[x]-L[x])+1) R[x]-=(t2-t1+1)*dt,pushup(x);
else{
if((u=mn(rs))==0) rs=++cnt,fa[cnt]=x;
else splay(u,x),c[u][0]=++cnt,fa[cnt]=u;
R[cnt]=R[x],R[x]=L[x]+(t1-2)*dt,L[cnt]=R[x]+(t2-t1+2)*dt;
pushup(cnt),pushup(rs),sum[x]=0,pushup(x);
}
}
}
int main(){
n=read(),T=read();
for(int i=1;i<=n;i++) m=read(),ins(i-1,m,m);
while(T--){
tpe=read(),X=read();
if(tpe==2) printf("%d\n",query(X));
else if(tpe==1) Y=read(),del(X,Y);
else tpe=X, X=read(),Y=read(),ins(tpe,X,Y);
}
return 0;
}

浙公网安备 33010602011771号