社区讨论

萌新刚学替罪羊树 1ms,MLE 0pts 求助!

P2286[HNOI2004] 宠物收养场参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@lo18hiue
此快照首次捕获于
2023/10/22 16:55
2 年前
此快照最后确认于
2023/11/02 16:45
2 年前
查看原帖
rt,样例能过
C
#include<bits/stdc++.h>
#define pre(x) kth(root,nlt(root,x) )
#define suf(x) kth(root,nlt(root,x+1)+1)
using namespace std;
const double alpha=0.75;
const int N=8e4+1;
int n,len,dfn[N];
int tot,root;

int read() {
	int x=0; char ch=0; while (!isdigit(ch) ) ch=getchar();
	while (isdigit(ch) ) x=(x<<3)+(x<<1)+(ch&15),ch=getchar();
	return x;
}
struct node {
	int l,r,val;
	int cnt,sz,dsz;
}T[N];

void pushup(int rt) {
	T[rt].sz=T[T[rt].l].sz+T[T[rt].r].sz+T[rt].cnt;
	T[rt].dsz=T[T[rt].l].dsz+T[T[rt].r].dsz+T[rt].cnt;
}
bool judge(int rt) {
	return (T[rt].cnt&&max(T[T[rt].l].sz,T[T[rt].r].sz)>T[rt].sz*alpha)||T[rt].dsz<T[rt].sz*alpha;
}
void get(int rt) {
	if (T[rt].l) get(T[rt].l);
	if (T[rt].cnt) dfn[++len]=rt;
	if (T[rt].r) get(T[rt].r);
}
int build(int l,int r) {
	if (l>r) return 0; int mid=l+r>>1,rt=dfn[mid];
	T[rt].l=build(l,mid-1),T[rt].r=build(mid+1,r);
	return rt;
}
void rebuild(int &rt) {
	get(rt),rt=build(1,len);
}
void insert(int &rt,int x)
{
	if (!rt) {
		rt=++tot; if (!root) root=rt;
		T[rt].cnt=T[rt].sz=T[rt].dsz=1;
		T[rt].val=x; return;
	}
	if (T[rt].val==x) T[rt].cnt++;
	else if (x<T[rt].val) insert(T[rt].l,x);
	else insert(T[rt].r,x); pushup(rt);
	if (judge(rt) ) rebuild(rt);
}
void erase(int &rt,int x)
{
	T[rt].dsz--;
	if (T[rt].val==x) T[rt].cnt--;
	else if (x<T[rt].val) erase(T[rt].l,x);
	else erase(T[rt].r,x); pushup(rt);
	if (judge(rt) ) rebuild(rt);
}
int nlt(int rt,int x)
{
	if (!rt) return 0;
	if (T[rt].cnt&&T[rt].val==x) return T[T[rt].l].dsz;
	else if (x<T[rt].val) return nlt(T[rt].l,x);
	else return T[T[rt].l].dsz+T[rt].cnt+nlt(T[rt].r,x);
}
int kth(int rt,int k)
{
	if (T[rt].l==T[rt].r) return T[rt].val;
	if (k<=T[T[rt].l].dsz) return kth(T[rt].l,k);
	if (T[T[rt].l].dsz<k&&k<=T[T[rt].l].dsz+T[rt].cnt) return T[rt].val;
	return kth(T[rt].r,k-T[T[rt].l].dsz-T[rt].cnt);
}
int main()
{
	n=read();
	int now=0;
	int sum=0;
	while (n--) {
		int op=read(),x=read();
		if (!op) insert(root,x),now++;
		else {
			if (!now) continue;
			int a=pre(x),b=suf(x);
			if (x-a<b-x) sum+=x-a,erase(root,a);
			else sum+=b-x,erase(root,b);
			sum%=1000000,now--;
		}
	}
	printf("%d",sum);
	return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...