1. 程式人生 > 其它 >Luogu P1110 報表統計

Luogu P1110 報表統計

Luogu 1110 報表統計

solution

\(\quad\)insert i k 就維護一個 vector

\(\quad\)MIN_GAP 每次插入會破壞一對關係,增加兩對關係。增加好說,破壞怎麼辦?

\(\quad\)我們可以維護兩個堆,一個堆記錄加入的數,一個堆記錄刪除的數,但要輸出時,如果兩個堆頂數值相同,那就不斷一起彈出即可。事實上這是一種很好的方法。

\(\quad\)MIN_SORT_GAP 就每次插入的時候找一下前驅後繼,然後更新值,這裡有一個小小的優化,就是當 MIN 取到 0 時,就不用再取更新了。

code

#include<bits/stdc++.h>
#define int long long
#define fo(i,j,k) for(register int i=j;i<=k;++i)
#define fd(i,j,k) for(register int i=j;i>=k;--i)
using namespace std;
const int N=1000100,inf=(1<<31)-1;
inline int read(){
	int ret=0,f=0;
	char ch=getchar();
	while(ch<'0' || ch>'9') {if(ch='-') f=1;ch=getchar();}
	while(ch>='0' && ch<='9'){ret=(ret<<1)+(ret<<3)+ch-(1<<4)-(1<<5);ch=getchar();}
	return f?-ret:ret;
}
int root;
int n,m,a[N],min_sg=inf;
struct splay_tree{
	int ch[N][2],fa[N],val[N],size[N],tot;
	#define lson ch[x][0]
	#define rson ch[x][1]
	inline int find_son(int x){return (x=ch[fa[x]][1]);}
	inline void update(int x){size[x]=size[lson]+size[rson]+1;}
	inline void connect(int x,int f,int son){fa[x]=f;ch[f][son]=x;}
	inline void rotate(int x){
		int y=fa[x];
		int z=fa[y];
		int xson=find_son(x);
		int yson=find_son(y);
		int b=ch[x][xson^1];
		connect(b,y,xson);
		connect(y,x,xson^1);
		connect(x,z,yson);
		update(y);update(x);
	}
	inline void splay(int x,int goal){
		while(fa[x]!=goal){
			int y=fa[x];
			if(fa[y]=goal) rotate(x);
			else if(find_son(x)==find_son(y)) rotate(y),rotate(x);
			else rotate(x),rotate(x);
		}
		if(!goal) root=x;
	}
	inline int pre(int k){
		int now=root,minn=-inf;
		while(now){
			if(val[now]<k && val[now]>minn){minn=val[now];}
			if(val[now]<k) now=ch[now][1];
			else now=ch[now][0];
		}
		return minn;
	}
	inline int nxt(int k){
		int now=root,maxx=inf;
		while(now){
			if(val[now]>k && val[now]<maxx){maxx=val[now];}
			if(val[now]>k) now=ch[now][0];
			else now=ch[now][1];
		}
		return maxx;
	}
	inline int find(int k){
		int now=root;
		while(1){
			if(val[now]==k) {
				splay(now,0);
				return now;}
			if(val[now]<k) now=ch[now][1];
			else now=ch[now][0];
			if(!now) return 0;
		}
	}
	int newnode(int k){
		val[++tot]=k;
		size[tot]=1;
		return tot;
	}
	inline void insert(int k){
		int p=find(k);
		if(p){splay(p,0);min_sg=0;return ;}
		int p1=find(pre(k)),p2=find(nxt(k));
		splay(p1,0);
		splay(p2,p1);
		ch[p2][0]=newnode(k);
		fa[tot]=p2;
		update(p2);update(p1);
	}
	inline void init(){
		root=1;
		tot=2;
		val[1]=-inf;val[2]=inf;
		ch[1][1]=2;fa[2]=1;
		size[1]=2;size[2]=1;
	}
	#undef lson
	#undef rson
}t;
vector<int> v[N];
priority_queue< int ,vector<int> ,greater<int> > p_in;
priority_queue< int ,vector<int> ,greater<int> > p_del;
signed main(){
	// freopen("P1110_7.in","r",stdin);
	n=read();m=read();
	t.init();
	fo(i,1,n) {		
		a[i]=read();
		if(min_sg){
			int y=a[i];
			int t1=abs(y-t.pre(y));
			int t2=abs(y-t.nxt(y));
			min_sg=min(min(t1,t2),min_sg);
			}
		t.insert(a[i]);
		v[i].push_back(a[i]);
	}
	fo(i,1,n-1) p_in.push(abs(a[i]-a[i+1]));
    fo(i,1,m){
		char op[13];
		scanf("%s",op);
		int l=strlen(op);
		if(l==6){
			int x=read(),y=read();
			v[x].push_back(y);
			if(min_sg){
				int t1=abs(y-t.pre(y));
				int t2=abs(y-t.nxt(y));
				min_sg=min(min(t1,t2),min_sg);
			}
			t.insert(y);
			p_in.push(abs(v[x][v[x].size()-2]-y));
			p_in.push(abs(a[x+1]-y));
			p_del.push(abs(v[x][v[x].size()-2]-a[x+1]));
		}
		else if(l==7){
			while(p_in.size() && p_del.size() && (p_in.top()=p_del.top())){
				p_in.pop();
				p_del.pop();
			}
			printf("%d\n",p_in.top());
		}
		else{
			printf("%d\n",min_sg);
		}
	}
	// cout<<t.tot<<endl;
	return 0;
}