这个题可以发现整个面积可以被拆成许多条线段的询问,然后排个序,特判一下,判出来是加还是减,然后算就好了。
代码:(没有AC,错误代码)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<queue>
#define ll long long
using namespace std;
inline int read(){
int x=0;char ch=' ';int f=1;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
const int inf=2000000000;
int n;
struct line{
ll x,y1,y2;
int t;
line(){}
line(int xx,int yy1,int yy2){
if(yy1>yy2)swap(yy1,yy2);
this->x=xx;
this->y1=yy1;
this->y2=yy2;
}
inline bool operator > (const line& b) const {
return y2>b.y2;
}
}a[50001];
int x[50001],y[50001];
bool cmp1(line& x,line& y){
return x.x>y.x;
}
bool cmp2(line& x,line& y){
return x.y1==y.y1?x.x>y.x:x.y1<y.y1;
}
ll bd=-inf;
priority_queue<line,vector<line>,greater<line> > q;
int main(){
freopen("bw.in","r",stdin);
freopen("bw.out","w",stdout);
n=read();
int mn=inf;
int mx=-inf;
for(int i=1;i<=n;i++){
x[i]=read();
y[i]=read();
mn=min(mn,y[i]);
mx=max(mx,y[i]);
}
a[1]=line(x[1],y[1],y[n]);
for(int i=2;i<=n;i+=2){
a[i/2+1]=line(x[i],y[i],y[i+1]);
}
sort(a+1,a+n/2+1,cmp2);
for(int i=1;i<=n/2;i++){
while(!q.empty()&&q.top().y2<=a[i].y1){
q.pop();
}
int opt=q.size()/2;
if(i&1){
if(opt&1){
a[i].t=-1;
}
else{
a[i].t=1;
}
}
else{
if(opt&1){
a[i].t=1;
}
else{
a[i].t=-1;
}
}
q.push(a[i]);
}
sort(a+1,a+n/2+1,cmp1);
ll bai=0;
ll hei=0;
for(int i=1;i<=n/2;i++){
if((a[i].x+a[i].y1)&1){
//hei
bool c1=(a[i].y2-a[i].y1)&1;
bool c2=(a[i].x-bd)&1;
ll num=(a[i].y2-a[i].y1)*(a[i].x-bd);
if(c1&&c2){
hei+=a[i].t*(num/2+1);
bai+=a[i].t*(num/2);
}
else{
hei+=a[i].t*(num/2);
bai+=a[i].t*(num/2);
}
}
else{
//bai
bool c1=(a[i].y2-a[i].y1)&1;
bool c2=(a[i].x-bd)&1;
ll num=(a[i].y2-a[i].y1)*(a[i].x-bd);
if(c1&&c2){
hei+=a[i].t*(num/2);
bai+=a[i].t*(num/2+1);
}
else{
hei+=a[i].t*(num/2);
bai+=a[i].t*(num/2);
}
}
}
printf("%I64d %I64d",hei,bai);
return 0;
}