CF2257D Bermuda Rectangle

CF2257D Bermuda Rectangle

本来以为就是找两个分界点,结果最后写下来发现细节挺多的。。。

\(S\) 的矩形呈阶梯状,肯定要先按形状把贡献存下来。

高度分界点记为 \(l\),完整分界点记为 \(r\)

手玩一下发现有四类矩形产生贡献:

高度 \(\ge y\) 且完整在 \((x, y)\) 内的。

高度 \(\ge y\) 且部分在 \((x, y)\) 内的。(这类容易漏掉还有很多小细节,比如高度要取 \(\min(y, h_i)\)

高度 \(\le y\) 且完整在 \((x, y)\) 内的。

高度 \(\le y\) 且部分在 \((x, y)\) 内的。

分界点用二分查找就行了,注意 \(l\) 要满足 \(rk[l] \le x\),所以建议手写一个二分。

时间复杂度 \(O(qlog {\sqrt{S}})\)。记得算一下内存。

其实反思一下,之所以把第二类漏掉了主要还是因为考虑的样例情况少了。还是要勤举例勤动手。

#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l); i <= (r); ++ i)
#define G(i,r,l) for(int i(r); i >= (l); -- i)
using namespace std;
using ll = long long;
const int N = 11000000;
int T, q, cnt;
ll S, rk[N], sum[N];
void ins(ll x){
	++ cnt;
	rk[cnt] = x;
}
int FInd(ll x, ll y){
	int l = 0, r = cnt + 1, mid;
	while(l + 1 < r){
		mid = (l + r) >> 1;
		if(rk[mid] <= x && S / rk[mid] >= y) l = mid;
		else r = mid;
	}
	return l;
}
void Main(){
	cnt = 0;
	cin >> S >> q;
	int b = sqrt(S); 
	F(i, 1, b){
		if(S % i == 0){
			ins(i);
			ins(S / i); 
		}
	}
	sort(rk + 1, rk + cnt + 1);
	F(i, 1, cnt){
		ll x = rk[i];
		sum[i] = sum[i - 1] + S / x * (rk[i] - rk[i - 1]); // stair-like value, store as the stair 
	}
//	printf("cnt = %d :\t", cnt);
//	F(i, 1, cnt) printf("%lld\t", rk[i]);
//	printf("\n");
	while(q --){
		ll x, y, tmp1 = 0, tmp2 = 0, tmp3 = 0, ans = 0;
		cin >> x >> y;
		int l, r;
		
		l = FInd(x, y);
		
		r = upper_bound(rk + 1, rk + cnt + 1, x) - rk - 1;//wan zheng kuai de bian jie 
//		l = lower_bound(rk + 1, rk + r + 1, S / y) - rk;
		 
//		printf("l = %d\tr = %d\n", l, r); 
		if(l <= r){ // have over-complete rectagle
			tmp1 = y * rk[l];
			tmp2 = sum[r] - sum[l];	
		}
		else{ // low height
			tmp1 = y * rk[r]; 
		}
		if(r < cnt) tmp3 = (x - rk[r]) * min(y, (S / rk[r + 1]));
//		printf("tmp1 = %lld\ttmp2 = %lld\ttmp3 = %lld\n", tmp1, tmp2, tmp3);
		ans = tmp1 + tmp2 + tmp3;
		cout << ans << '\n';
	} 
	return ;
} 
signed main(){
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> T;
	while(T --) Main();
	return fflush(0), 0;
}
posted @ 2026-08-27 16:56  superl61  阅读(11)  评论(0)    收藏  举报