伟大发明
查看原帖
伟大发明
907536
one_zero_two_zero楼主2024/11/15 09:32

以下代码通过使用二分等算法,可在 O(nlog2n)O(nlog^2n) 的时间复杂度内

求出一个序列的最大值

代码如下

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define cur 300010
#define lowbit(x) ((x) & (-x))
using namespace std;

int N, ans = -1;
int A[300005];
int l = 0, r = 1000000000;
long long target;
int C[600055];

void update(int idx, int val){
	for (int i = idx; i <= cur + N; i += lowbit(i)){
		C[i] += val;
	}
}

int query(int idx){
	int res = 0;
	for (int i = idx; i; i -= lowbit(i)){
		res += C[i];
	}
	return res;
}

bool check(int x){
	memset(C, 0, sizeof(C));
	int nowval = 0;
	long long cnt = 0; // how much [i, j] med <= x
	for (int i = 1; i <= N; i ++){
		int tmp = (A[i] <= x) ? -1 : 1;
		update(cur + nowval, 1);
		nowval += tmp;
		cnt += i - query(cur + nowval - 1);
	}
	return cnt >= target;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("../data.in", "r", stdin);
    freopen("../data.out", "w", stdout);
#endif

	scanf("%d", &N);
	target = 1LL * (N + 1) * N / 2;
	for (int i = 1; i <= N; i ++){
		scanf("%d", &A[i]);
	}
	while (l <= r){
		int mid = (l + r) >> 1;
		if (check(mid)){
			ans = mid;
			r = mid - 1;
		}else{
			l = mid + 1;
		}
	}
	printf("%d\n", ans);

    return 0;
}

可以试试看

2024/11/15 09:32
加载中...