萌新求助这题卡常,带旋treap,TLE最后一个点。
查看原帖
萌新求助这题卡常,带旋treap,TLE最后一个点。
26525
poplpr楼主2020/7/16 19:07
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<vector> 
#include<cstdlib>
#include<ctime>
using namespace std;
#define IL inline
#define ri register int
IL void read(int &x) {
	x=0; int f=1; char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-')f=-1; ch=getchar();}
	while(isdigit(ch)) {x = x*10+ch-'0'; ch=getchar();}
}
int buf[23];
IL void write(int i) {
	int p = 0;
	if(i < 0) {putchar('-'); i=-i;}
	if(i == 0) {buf[p++] = 0;}
	else while(i) {
		buf[p++] = i % 10;
		i /= 10;
	}
	for(ri j=p-1;j>=0;j--) putchar(buf[j] + '0');
}

struct Node* null;
struct Node {
	int v,r,sz,cnt;
	Node* ch[2];
	IL Node() {}
	IL Node(int v):v(v) {r=rand(); sz=cnt=1; ch[0]=ch[1]=null;}
	IL bool operator < (const Node& rhs) const {return r < rhs.r;}
	IL int cmp(int x) const {
		if(x == v) return -1;
		return v < x;
	}
	IL void upd() {sz = ch[0]->sz + ch[1]->sz + cnt;}
};
IL void initnull() { null = new Node(); null->v=null->sz=null->cnt=null->r=0;}
IL void rotate(Node* &o,int d) {
	Node *k = o->ch[d^1]; o->ch[d^1] = k->ch[d]; k->ch[d] = o;
	o->upd(); k->upd(); o = k;
}
void insert(Node* &o,int x) {
	if(o == null) {o = new Node(x); return;}
	o->sz++;
	int d = o->cmp(x);
	if(d == -1) {o->cnt++; return;}
	insert(o->ch[d],x);
	if(o->r < o->ch[d]->r) rotate(o,d^1);
	o->upd();
}
void erase(Node* &o,int x) {
	if(o == null) {return;}
	int d = o->cmp(x);
	if(d == -1) {
		Node* u = o;
		if(o->cnt > 1) {o->cnt--; o->sz--; return;}
		if(o->ch[0] != null && o->ch[1] != null) {
			int d2 = o->ch[0]->r > o->ch[1]->r;
			rotate(o,d2); erase(o->ch[d2],x);
		}
		else {
			if(o->ch[0] == null) o = o->ch[1]; else o = o->ch[0];
			delete u;
		}
	}
	else erase(o->ch[d],x);
	if(o != null) o->upd();
}
int query_kth(Node* o,int k) {
	if(o == null) return 0;
	if(k <= o->ch[0]->sz) return query_kth(o->ch[0],k);
	else if(k > o->ch[0]->sz+o->cnt) return query_kth(o->ch[1],k - o->ch[0]->sz - o->cnt);
	return o->v;
}
void query_pre(Node *o,int x,Node* &ans) {
	if(o == null) return;
	if(o->v == x) {ans = o; return;}
	if(o->v < x) {ans = o; query_pre(o->ch[1],x,ans);}
	else query_pre(o->ch[0],x,ans);
}
void query_sub(Node *o,int x,Node* &ans) {
	if(o == null) return;
	if(o->v == x) {ans = o; return;}
	if(x < o->v) {ans = o; query_sub(o->ch[0],x,ans);}
	else query_sub(o->ch[1],x,ans);
}
IL int pre(Node *o,int x) { Node *ans=null; query_pre(o,x,ans); return ans == null ? -1 : ans->v;}
IL int sub(Node *o,int x) { Node *ans=null; query_sub(o,x,ans); return ans == null ? -1 : ans->v;}

Node *val, *diff;

const int N = 5e5 + 3;
const int INF = 1e9 + 7;

int n,m,ans;
char op[21];
vector<int> a[N];

int main() {
	srand(19260817); 
	read(n); read(m); ans = INF;
	initnull(); val = diff = null;
	for(ri i=1;i<=n;i++) {
		int v; read(v);
		a[i].push_back(v);
		int l = pre(val,v), r = sub(val,v);
		if(l != -1) ans = min(ans,abs(v-l));
		if(r != -1) ans = min(ans,abs(v-r));
		insert(val,v);
		if(i > 1) insert(diff,abs(a[i][0]-a[i-1][0]));
	}
	while(m--) {
		scanf("%s",op);
		if(op[4] == 'R') {
			int pos,k; read(pos); read(k);
			int l = pre(val,k), r = sub(val,k);
			insert(val,k);
			if(l != -1) ans = min(ans,abs(k-l));
			if(r != -1) ans = min(ans,abs(k-r));
			if(pos != n) erase(diff,abs(a[pos][a[pos].size()-1] - a[pos+1][0]));
			insert(diff,abs(a[pos][a[pos].size()-1]-k));
			if(pos != n) insert(diff,abs(k-a[pos+1][0]));
			a[pos].push_back(k);
		}
		if(op[4] == 'G') { write(query_kth(diff,1)); putchar('\n');}
		if(op[4] == 'S') { write(ans); putchar('\n');}
	}
	return 0;
}
2020/7/16 19:07
加载中...