我的可删堆*2+FHQ的做法哪里错了?
查看原帖
我的可删堆*2+FHQ的做法哪里错了?
822145
chenzhaoxu2027楼主2024/9/22 20:38

我的思路就是:

把两种询问的答案分别放进可删堆里面,每一次插入的时候就更新两种可删堆。只有 MIN_SORT_GAP 询问要用平衡树,我猜测大概率是这种询问有问题。

WA 14,只有 Test 1 对了。

#include <bits/stdc++.h>
using namespace std;

struct heap_can_delete {
	priority_queue<int,vector<int>,greater<int> > A, B;
	void ins(int x) {
		A.push(x);
	}
	void del(int x) {
		B.push(x);
	}
	int query() {
		while (!B.empty() && A.top() == B.top()) {
			A.pop();
			B.pop();
		}
		return A.top();
	}
} H1, H2;
int n;
int a[1000005];

struct FHQ_treap {
	struct node {
		int val, pty, sz;
		int ls, rs;
	} t[2000005];
	int cnt = 0, root = 0;
	void pushup(int x) {
		t[x].sz = t[t[x].ls].sz + 1 + t[t[x].rs].sz;
	}
	int newnode(int val) {
		cnt++;
		t[cnt].sz = 1;
		t[cnt].val = val;
		t[cnt].pty = rand();
		return cnt;
	}
	int merge(int x,int y){
		if(!x||!y){
			return x+y;
		}
		if(t[x].pty<t[y].pty){
			t[x].rs=merge(t[x].rs,y);
			pushup(x);
			return x;
		}
		else{
			t[y].ls=merge(x,t[y].ls);
			pushup(y);
			return y;
		}
	}
	void split(int now, int k, int &x, int &y) {
		if (!now) {
			x = 0;
			y = 0;
		} else if (t[now].val <= k) {
			x = now;
			split(t[now].rs, k, t[now].rs, y);
			pushup(now);
		} else {
			y = now;
			split(t[now].ls, k, x, t[now].ls);
			pushup(now);
		}
	}

	int kth(int now, int k) {
		while (1) {
			if (k <= t[t[now].ls].sz) {
				now = t[now].ls;
			} else if (k == t[t[now].ls].sz + 1) {
				return now;
			} else {
				k -= t[t[now].ls].sz + 1;
				now = t[now].rs;
			}
		}
	}

	void ins(int val, int x, int y) {
		split(root, val, x, y);
		int newval = newnode(val);
		int tmp = merge(x, newval);
		root = merge(tmp, y);
	}

	void dlt(int val, int x, int y, int z) {
		split(root, val, x, z);
		split(x, val - 1, x, y);
		y = merge(t[y].ls, t[y].rs);
		int w = merge(x, y);
		root = merge(w, z);
	}

	int rnk(int val, int x, int y) {
		split(root, val - 1, x, y);
		int res = t[x].sz + 1;
		root = merge(x, y);
		return res;
	}

	int num(int val) {
		return t[kth(root, val)].val;
	}
	int pre(int val,int x,int y){
		split(root,val-1,x,y);
		int res=t[kth(x,t[x].sz)].val;
		root=merge(x,y);
		return res;
	}
	int suf(int val,int x,int y){
		split(root,val,x,y);
		int res=t[kth(y,1)].val;
		root=merge(x,y);
		return res;
	}
} Treap;
int elecnt = 0;
int fl1 = 0;

signed main() {
	int n, m;
	cin >> n >> m;
	int X, Y, Z, W;
	Treap.ins(-1e9, X, Y);
	Treap.ins(1e9, X, Y);
	elecnt = 2;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		if (fl1==0) {
			int cntsame = Treap.rnk(Treap.suf(a[i], X, Y), Z, W) - Treap.rnk(Treap.pre(a[i], X, Y), Z, W) - 1;
//			cout<<cntsame<<"\n";
			if (cntsame >= 1) {
				fl1 = 1;
			} else {
				Treap.ins(a[i], X, Y);
				elecnt++;
			}
		}
		if (i != 1) {
			H1.ins(max(a[i], a[i - 1]) - min(a[i], a[i - 1]));
//			cout<<"push "<<max(a[i], a[i - 1]) - min(a[i], a[i - 1])<<"\n";
		}
	}
	for (int i = 1; i <= n; i++) {
		if (fl1==0) {
			int tmp = Treap.pre(a[i], X, Y);
			H2.ins(a[i] - tmp);
		}
	}
//	cout << H2.query() << "\n";
	while (m--) {
		string op;
		cin >> op;
		if (op == "INSERT") {
			int x, y;
			cin >> x >> y;
			if (x != n) {
				H1.del(max(a[x], a[x + 1]) - min(a[x], a[x + 1]));
//				cout<<"pop "<<max(a[x], a[x + 1]) - min(a[x], a[x + 1])<<"\n";
				H1.ins(max(a[x + 1], y) - min(a[x + 1], y));
//				cout<<"push "<<max(a[x + 1], y) - min(a[x + 1], y)<<"\n";
			}
			H1.ins(max(a[x], y) - min(a[x], y));
//			cout<<"push "<<max(a[x], y) - min(a[x], y)<<"\n";
			a[x]=y;
			if (fl1==0) {
				int cntsame = Treap.rnk(Treap.suf(y, X, Y), Z, W) - Treap.rnk(Treap.pre(y, X, Y), Z, W) - 1;
				if (cntsame >= 1) {
					fl1 = 0;
				} else {
					Treap.ins(y, X, Y);
					elecnt++;
					int tmp = Treap.pre(y, X, Y);
					int tmp2 = Treap.suf(y, X, Y);
					H2.ins(y - tmp);
					H2.ins(tmp2 - y);
				}
			}
		}
		if (op == "MIN_GAP") {
			cout << H1.query() << "\n";
		}
		if (op == "MIN_SORT_GAP") {
			if (fl1) {
				cout << 0 << "\n";
			} else {
				cout << H2.query() << "\n";
			}
		}
	}
	return 0;
}
2024/9/22 20:38
加载中...