10分球条(WA #1~9)
查看原帖
10分球条(WA #1~9)
763215
foglake楼主2024/8/29 13:31

帮帮蒟蒻吧QaQ

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 3e5 + 10;
int n, q, len;
long long t[maxn], ans;
pair <pair<int, int>, int> que[maxn]; //存储提问(依次存储右端点、左端点、编号)
pair <int, int> num[maxn], seg[2 * maxn]; // num 存储数列,seg 存储提问(依次存储右端点、左端点)
int lowbit(int x) {
	return x & -x;
}
void update(int x) {
	if (x > n) return;
	t[x] ++;
	update(x + lowbit(x));
}
long long get_sum(int x) {
	if (x < 1) return 0;
	return t[x] + get_sum(x - lowbit(x));
}
pair <int, int> buildseg(int x, int y) { // 建立线段
	return {max(x, y), min(x, y)};
}
int main() {
	scanf("%d%d", &n, &q);
	for (int i = 1; i <= n; i++) {
		scanf("%d", &num[i].first);	
		num[i].second = i;
	}
	sort(num + 1, num + 1 + n);
	for (int i = 1; i <= n; i++) {
		if (n == 1) break; //特判
		int ssn = num[i + 1].second,sst = num[i].second, ssb = num[i - 1].second;
		int sfn = num[i + 1].first, sft = num[i].first, sfb = num[i - 1].first;
		if (i == 1) seg[++len] = buildseg(sst, ssn);
		else if (i == n) seg[++len] = buildseg(ssb, sst);
		else{
			if (sft - sfb >= sfn - sft) seg[++len] = buildseg(ssn, sst);
			if (sft - sfb <= sfn - sft) seg[++len] = buildseg(sst, ssb);
		}
	}
	if (len) sort(seg + 1, seg + 1 + len);
	for (int i = 1; i <= q; i++) {
		int l, r;
		scanf("%d%d", &l, &r);
		que[i] = {{r, l}, i};
	}
	sort(que + 1, que + 1 + q); // 提问先排序
	int p = 0;
	for (int i = 1; i <= n; i++) {
		while (seg[p].first <= que[i].first.first && p < len) update(seg[++p].second);
		// 加入已被覆盖的线段
		ans += (long long)(p - get_sum(que[i].first.second - 1)) * que[i].second;//统计答案
	}
	printf("%lld", ans);
}
2024/8/29 13:31
加载中...