[ZJOI2007]报表统计
落谷
今早手打了遍splay,妹子oj的rating总是那么奇葩
然后,既然都写了。不如做一道splay;
T^T 我的二重splay不能过最后一个点
t[0]维护min_sort_gap
t[1]维护min_gap
#include<bits/stdc++.h>
#define re return
#define ll long long
#define inc(i,l,r) for(int i=l;i<=r;++i)
const int maxn=1e6+5;
using namespace std;
template<typename T>inline void rd(T&x)
{
char c;bool f=0;
while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
x=c^48;
while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
if(f)x=-x;
}
int n,a[maxn>>1],last[maxn>>1],m;
ll minn=99999999999999;
//int siz[maxn>>1];
struct node
{
int rt,tot,ch[maxn][2],val[maxn],size[maxn],cnt[maxn],fa[maxn];
inline bool chk(int x){re ch[fa[x]][1]==x;}
inline void pushup(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+cnt[x];}
inline void rotate(int x)
{
int y=fa[x],z=fa[y],k=chk(x),w=ch[x][k^1];
ch[z][chk(y)]=x;fa[x]=z;
ch[y][k]=w;fa[w]=y;
ch[x][k^1]=y;fa[y]=x;
pushup(y);pushup(x);
}
inline void splay(int x,int goal=0)
{
while(fa[x]!=goal)
{
int y=fa[x],z=fa[y];
if(z!=goal)
//chk(x)==chk(y)?rotate(y):rotate(x);
rotate(y);
rotate(x);
}
if(!goal)rt=x;
}
inline void insert(int x)
{
int u=rt,p=0;
while(u&&val[u]!=x)
{
p=u;
u=ch[u][x>val[u]];
}
if(u)++cnt[u];
else
{
u=++tot;
if(p)ch[p][x>val[p]]=u;
size[u]=cnt[u]=1;
ch[u][0]=ch[u][1]=0;
fa[u]=p;
val[u]=x;
}
splay(u);
}
inline int kth(int k)
{
int u=rt;
while(2333)
{
int y=ch[u][0];
if(k>cnt[u]+size[y])k=k-cnt[u]-size[y],u=ch[u][1];
else if(k<=size[y])u=y;
else re u;
}
}
inline void find(int x)
{
int u=rt;
while(ch[u][x>val[u]]&&x!=val[u])
u=ch[u][x>val[u]];
splay(u);
}
inline int nt(int x,int f)
{
find(x);
if(!f&&val[rt]<x)re rt;
if( f&&val[rt]>x)re rt;
int u=ch[rt][f];
f^=1;
while(ch[u][f])u=ch[u][f];
re u;
}
inline void dete(int x)
{
int l=nt(x,0),r=nt(x,1);
splay(l,0);splay(r,l);
int u=ch[r][0];
if(cnt[u]>1)--cnt[u],pushup(u);
else ch[r][0]=0;
pushup(r);
pushup(l);
}
inline void vivi(int x)
{
insert(x);
ll l=val[nt(x,0)];
if(cnt[rt]>1)
{
minn=0; re;
}
ll r=val[nt(x,1)];
minn=min(minn,min(x-l,r-x));
}
}t[2];
int main()
{
//freopen("in.txt","r",stdin);
rd(n);rd(m);
t[1].rt=t[1].tot=0;
t[0].rt=t[0].tot=0;
t[1].insert(2147483647);t[1].insert(-2147483647);
t[0].insert(2147483647);
t[0].insert(-2147483647);
rd(a[1]);last[1]=a[1];
t[0].insert(a[1]);
inc(i,2,n)
{
rd(a[i]);
last[i]=a[i];
if(minn)t[0].vivi(a[i]);
t[1].insert(abs(a[i]-a[i-1]));
}
char opt[20];
int x,y,cnt=0;
inc(i,1,m)
{
scanf("%s",opt);
if(opt[0]=='I')
{
rd(x),rd(y);
int v=last[x];
last[x]=y;
t[1].dete(abs(a[x+1]-v));
t[1].insert(abs(y-v));
t[1].insert(abs(y-a[x+1]));
if(minn)t[0].vivi(y);
}
else if(opt[4]=='G')
{
printf("%d\n",t[1].val[t[1].nt(-2147483647,1)]);
}
else
{
printf("%lld\n",minn);
}
}
re 0;
}
所以让我们用堆维护min_gap,共创美好世界
q1维护删除数
q2维护插入数
#include<bits/stdc++.h>
#define re return
#define ll long long
#define inc(i,l,r) for(int i=l;i<=r;++i)
const int maxn=1e6+5;
using namespace std;
template<typename T>inline void rd(T&x)
{
char c;bool f=0;
while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
x=c^48;
while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
if(f)x=-x;
}
int n,a[maxn>>1],last[maxn>>1],m;
ll minn=99999999999999;
//int siz[maxn>>1];
int rt,tot,ch[maxn][2],val[maxn],size[maxn],cnt[maxn],fa[maxn];
inline bool chk(int x){re ch[fa[x]][1]==x;}
inline void pushup(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+cnt[x];}
inline void rotate(int x)
{
int y=fa[x],z=fa[y],k=chk(x),w=ch[x][k^1];
ch[z][chk(y)]=x;fa[x]=z;
ch[y][k]=w;fa[w]=y;
ch[x][k^1]=y;fa[y]=x;
pushup(y);pushup(x);
}
inline void splay(int x,int goal=0)
{
while(fa[x]!=goal)
{
int y=fa[x],z=fa[y];
if(z!=goal)chk(x)==chk(y)?rotate(y):rotate(x);
rotate(x);
}
if(!goal)rt=x;
}
inline void insert(int x)
{
int u=rt,p=0;
while(u&&val[u]!=x)
{
p=u;
u=ch[u][x>val[u]];
}
if(u)++cnt[u];
else
{
u=++tot;
if(p)ch[p][x>val[p]]=u;
size[u]=cnt[u]=1;
ch[u][0]=ch[u][1]=0;
fa[u]=p;
val[u]=x;
}
splay(u);
}
inline int kth(int k)
{
int u=rt;
while(2333)
{
int y=ch[u][0];
if(k>cnt[u]+size[y])k=k-cnt[u]-size[y],u=ch[u][1];
else if(k<=size[y])u=y;
else re u;
}
}
inline void find(int x)
{
int u=rt;
while(ch[u][x>val[u]]&&x!=val[u])
u=ch[u][x>val[u]];
splay(u);
}
inline int nt(int x,int f)
{
find(x);
if(!f&&val[rt]<x)re rt;
if( f&&val[rt]>x)re rt;
int u=ch[rt][f];
f^=1;
while(ch[u][f])u=ch[u][f];
re u;
}
inline void dete(int x)
{
int l=nt(x,0),r=nt(x,1);
splay(l,0);splay(r,l);
int u=ch[r][0];
if(cnt[u]>1)--cnt[u],pushup(u);
else ch[r][0]=0;
pushup(r);
pushup(l);
}
inline void vivi(int x)
{
insert(x);
ll l=val[nt(x,0)];
if(cnt[rt]>1)
{
minn=0; re;
}
ll r=val[nt(x,1)];
minn=min(minn,min(x-l,r-x));
}
int main()
{
rd(n);rd(m);
priority_queue<int,vector<int>,greater<int> >q1,q2;
insert(2147483647);
insert(-2147483647);
rd(a[1]);last[1]=a[1];
insert(a[1]);
inc(i,2,n)
{
rd(a[i]);
last[i]=a[i];
if(minn)vivi(a[i]);
q2.push(abs(a[i]-a[i-1]));
}
char opt[20];
int x,y,cnt=0;
inc(i,1,m)
{
scanf("%s",opt);
if(opt[0]=='I')
{
rd(x),rd(y);
int v=last[x];
last[x]=y;
q1.push(abs(a[x+1]-v));
q2.push(abs(y-v));
q2.push(abs(y-a[x+1]));
if(minn)vivi(y);
}
else if(opt[4]=='G')
{
while(!q1.empty()&&q1.top()==q2.top())
{
q1.pop();
q2.pop();
}
printf("%d\n",q2.top());
}
else
{
printf("%lld\n",minn);
}
}
re 0;
}

浙公网安备 33010602011771号