社区讨论

对顶堆求助

学术版参与者 2已保存回复 2

讨论操作

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

当前回复
2 条
当前快照
1 份
快照标识符
@mid65f3e
此快照首次捕获于
2025/11/24 21:14
3 个月前
此快照最后确认于
2025/11/24 21:56
3 个月前
查看原帖
Slope Trick。
我使用对顶堆维护斜率分段点,算法正确性没有问题,对顶堆的理论复杂度应为 O(nlogn)O(n\log n),但是跑得特别慢,连 CF n=5000n=5000 都过不了,求助哪里有问题。
CPP
#include <cstdio>
#include <queue>
#include <vector>
using namespace std;
typedef long long LL;

const int MAX_N = 5e5+5;

int n, a[MAX_N];
LL kk, bb;
priority_queue<int> qmax;
priority_queue<int, vector<int>, greater<int> > qmin;

int main () {
	freopen("data.txt","r",stdin);
	scanf("%d",&n);
	for(int i = 1; i <= n; i ++) {
		scanf("%d",&a[i]);
		while(!qmin.empty()) {
			-- kk;
			bb += qmin.top();
			qmin.pop();
		}
		++ kk;
		bb -= a[i];
		qmin.push(a[i]);
		qmin.push(a[i]);
		while(!qmin.empty() && !qmax.empty() && qmin.top() < qmax.top()) {
			qmin.push(qmax.top());
			qmax.pop();
		}
		while(!qmin.empty() && (int)qmin.size() > kk) {
			qmax.push(qmin.top());
			qmin.pop();
		}
		while(!qmax.empty() && (int)qmin.size() < kk) {
			qmin.push(qmax.top());
			qmax.pop();
		}
//		if(i > 1e4) printf("i = %d  qmax_size = %u  qmin_size = %u\n",i,qmax.size(),qmin.size());
	}
	while(!qmin.empty()) {
		-- kk;
		bb += qmin.top();
		qmin.pop();
	}
	printf("%lld\n",bb);
	return 0;
}
数据生成器。
CPP
#include <random>
#include <ctime>
#include <cstdio>
using namespace std;
mt19937 RAND(time(NULL));

const int N = 1e5, V = 1e9;

int main () {
	freopen("data.txt","w",stdout);
	printf("%d\n",N);
	for(int i = 1; i <= N; i ++) {
		if(RAND()&1) {
			printf("%d ",-(int)RAND()%V);
		}
		else printf("%d ",(int)RAND()%V);
	}
	return 0;
}

回复

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

正在加载回复...