[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;
} 
posted @ 2019-08-12 10:27  凉如水  阅读(109)  评论(0)    收藏  举报