BZOJ 1058 [ZJOI2007]报表统计

题解:

SB的我打了无旋Treap,然后在洛谷上光荣的T了

BZOJ极限卡时A了

 (每个初始位置后面加入的数)的影响是可以直接算的,然后初始位置之间的影响用平衡树(线段树)来维护即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
const int maxn=1000009;
const int oo=1000000000;

int n,TT;

int abs(int x){
	if(x<0)return -x;
	else return x;
}

int nn=0,root=0;
int ch[maxn][2]={0},fix[maxn]={0},siz[maxn]={0},kyl[maxn]={0},kyr[maxn]={0},tl[maxn]={0},tr[maxn]={0},mn[maxn]={0};
void pushup(int x){
	siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
	if(ch[x][0]&&ch[x][1]){
		tl[x]=tl[ch[x][0]];
		tr[x]=tr[ch[x][1]];
		mn[x]=min(min(min(mn[ch[x][0]],mn[ch[x][1]]),abs(kyr[x]-tl[ch[x][1]])),abs(kyl[x]-tr[ch[x][0]]));
	}else if(ch[x][0]){
		tl[x]=tl[ch[x][0]];
		tr[x]=kyr[x];
		mn[x]=min(mn[ch[x][0]],abs(kyl[x]-tr[ch[x][0]]));
	}else if(ch[x][1]){
		tl[x]=kyl[x];
		tr[x]=tr[ch[x][1]];
		mn[x]=min(mn[ch[x][1]],abs(kyr[x]-tl[ch[x][1]]));
	}else{
		tl[x]=kyl[x];
		tr[x]=kyr[x];
		mn[x]=oo;
	}
}

int NewNode(int a,int b){
	int x=++nn;
	fix[x]=rand();
	siz[x]=1;
	kyl[x]=tl[x]=a;
	kyr[x]=tr[x]=b;
	mn[x]=oo;
	return x;
}

int Mer(int x,int y){
	if((!x)||(!y))return x+y;
	
	if(fix[x]<fix[y]){
		ch[x][1]=Mer(ch[x][1],y);
		pushup(x);
		return x;
	}else{
		ch[y][0]=Mer(x,ch[y][0]);
		pushup(y);
		return y;
	}
}

void Split(int now,int k,int &x,int &y){
	if(!now){
		x=y=0;
	}else{
		int l=ch[now][0];
		if(k>=siz[l]+1){
			x=now;
			Split(ch[now][1],k-(siz[l]+1),ch[now][1],y);
		}else{
			y=now;
			Split(ch[now][0],k,x,ch[now][0]);
		}
		pushup(now);
	}
}

void Updatapoint(int x,int k,int a){
	int l=ch[x][0];
	if(k==siz[l]+1){
		kyr[x]=a;
	}else if(k<siz[l]+1){
		Updatapoint(ch[x][0],k,a);
	}else if(k>siz[l]+1){
		Updatapoint(ch[x][1],k-(siz[l]+1),a);
	}
	pushup(x);
}
int sortgap=oo,nextgap=oo;

vector<int>G[maxn];

map<int,int>ma;
int main(){
	srand(19260817);
	scanf("%d%d",&n,&TT);
	for(int i=1;i<=n;++i){
		int x;scanf("%d",&x);
		G[i].push_back(x);
		root=Mer(root,NewNode(x,x));
		
		if(ma.count(x))sortgap=0;
		ma[x]=1;
		map<int,int>::iterator it=ma.lower_bound(x);
		if(it!=ma.begin()){
			--it;
			sortgap=min(sortgap,abs(x-(it->first)));
			++it;
		}
		++it;
		if(it!=ma.end())sortgap=min(sortgap,abs(x-(it->first)));
	}
	
	while(TT--){
		char opty[20];
		scanf("%s",opty);
		int x,y,z,k,a;	
		if(opty[4]=='R'){
			scanf("%d%d",&k,&a);
			G[k].push_back(a);
			int m=G[k].size();
			nextgap=min(nextgap,abs(G[k][m-2]-G[k][m-1]));
			Updatapoint(root,k,a);
//			Split(root,k,x,z);
//			Split(x,k-1,x,y);
//			root=Mer(Mer(x,NewNode(G[k][0],G[k][m-1])),z);
			
			if(ma.count(a))sortgap=0;
			ma[a]=1;
			map<int,int>::iterator it=ma.lower_bound(a);
			if(it!=ma.begin()){
				--it;
				sortgap=min(sortgap,abs(a-(it->first)));
				++it;
			}
			++it;
			if(it!=ma.end())sortgap=min(sortgap,abs(a-(it->first)));
			ma[a]=1;
		}
		if(opty[4]=='G'){
			printf("%d
",min(nextgap,mn[root]));
		}
		if(opty[4]=='S'){
			printf("%d
",sortgap);
		}
	}
	return 0;
}

  

自己还是太辣鸡了
原文地址:https://www.cnblogs.com/zzyer/p/8490936.html