题解:
注意到白点不被挡住的情况一定是白点一直往一个方向走。
不妨考虑一个黑点能挡住某个方向的哪些白点,画图可以发现是四周的三角形区域。
对于三角形区域,可以通过坐标旋转来转化为矩阵区域,之后问题便转化为:给四种颜色的一些区域,问有哪些区域同时有四种颜色,直接扫描线即可。
(细节有点多直接抄的楼教主的代码。。)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
inline int rd() {
char ch=getchar(); int i=0,f=1;
while(!isdigit(ch)) {if(ch=='-')f=-1; ch=getchar();}
while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=getchar();}
return i*f;
}
const int N=1e5+50;
int n,xc[N],yc[N];
multiset <int> s1,s2;
vector <pii> s;
inline LL solve(int odd) {
LL rs=0;
s.clear(); s1.clear(); s2.clear();
for(int i=1;i<=n;i++) if((xc[i]&1)==odd) s.push_back(make_pair((xc[i]+odd)/2,(yc[i]+odd)/2));
if(!s.size()) return 0;
sort(s.begin(), s.end());
for(int i=0;i<s.size();i++)
s2.insert(s[i].second);
for(int x0=s.front().first,p1=0,p2=0;x0<=s.back().first;++x0) {
while(p1<s.size() && s[p1].first<=x0) s1.insert(s[p1++].second);
while(p2<s.size() && s[p2].first<=x0) s2.erase(s2.find(s[p2++].second));
if(s1.size() && s2.size()) {
int t=max(*s1.begin(),*s2.begin()), u=min(*s1.rbegin(),*s2.rbegin());
if(u>t) rs+=u-t;
}
}
return rs;
}
int main() {
n=rd();
for(int i=1;i<=n;i++) {
int x=rd(), y=rd();
xc[i]=(x-y);
yc[i]=(x+y);
}
cout<<solve(0)+solve(1);
}