AT_abc449_d [ABC449D] Make Target 2 Solotion

暴力显然是不行的,我们考虑找数学规律。

解题思路

首先转化问题。黑色点的条件为 \(\max(|x|, |y|)\) 是偶数。这等价于:

  • \(|x| \geq |y|\) 时,\(x\) 为偶数。
  • \(|x| < |y|\) 时,\(y\) 为偶数。

两种情况黑色点集合显然互斥,所以我们可以分别计算这两种情况然后求和。

情况一

对于每个偶数 \(x \in [L, R]\),设 \(a = |x|\),则 \(y\) 的范围为 \([\max(D, -a), \min(U, a)]\),贡献的数量为 \(\min(U, a) - \max(D, -a) + 1\)

情况二

对于每个偶数 \(y \in [D, U]\),设 \(b = |y|\),则 \(|x| < b\) 等价于 \(-b + 1 \leq x \leq b - 1\),因此 \(x\) 的范围为 \([\max(L, -b + 1), \min(R, b - 1)]\),则贡献的数量为 \(\min(R, b - 1) - \max(L, -b + 1) + 1\)

复杂度 \(O(L+R+D+U)\),可过。

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	int L,R,D,U;
	cin>>L>>R>>D>>U;
	int ans=0;
	for(int x=L;x<=R;++x) if(!(x&1)){
		int l=max(D,-abs(x)),r=min(U,abs(x));
		if(l<=r)ans+=r-l+1;
	}
	for(int y=D;y<=U;++y) if(!(y&1)){
		int l=max(L,-abs(y)+1),r=min(R,abs(y)-1);
		if(l<=r) ans+=r-l+1;
	}
	cout<<ans;
	return 0;
}
posted @ 2026-03-27 21:25  vivid/stasis  阅读(5)  评论(0)    收藏  举报