给你一个n行m列的黑白块相间的棋盘,进行两次操作,第一次把(x1,y1)到(x2,y2)的区域全部涂白,第二次把(x3,y3)到(x4,y4)的区域全部涂黑,问你这样以后黑白各有多少块?
观察黑白块的分布我们可以得知从(a,b)到(c,d)的白、黑色块数量分别是(c-a+1)(d-b+1)/2+(a+b+1)%2和(c-a+1)(d-b+1)/2+(a+b)%2,所以我们可分别计算除两次操作区间的黑白块的数量(当然有写用不到),然后计算相交区间的黑白块的数量。
所以白色的数量就是总的白色的数量-第二次操作区间的白色的数量+在第一次操作区间而不在相交区间的黑色的数量。
有点容斥的意思哈
#include <iostream>
using namespace std;
typedef long long LL;
LL t,m,n,x1,x2,x3,x4,y1,y2,y3,y4,wt,bt,w1,b1,w2,b2,we,be,jx,jy;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
cin>>t;
while(t--){
cin>>m>>n>>x1>>y1>>x2>>y2>>x3>>y3>>x4>>y4;
LL u1 = min(x2,x4),u2 = max(x3,x1),u3 = min(y2,y4),u4 = max(y3,y1);
jx = max(u1 - u2+1,0LL);
jy = max(u3 - u4+1,0LL);
if(!jx||!jy) we = 0,be = 0;
else we = jx*jy/2 +(jx*jy%2?(u2+u3+1)%2:0), be = jx*jy/2 +(jx*jy%2?(u2+u3)%2:0);
wt = m*n/2+(m*n)%2;bt = m*n/2;
w1 = (x2-x1+1)*(y2-y1+1)/2+((x2-x1+1)*(y2-y1+1)%2?(x1+y1+1)%2:0);
b1 = (x2-x1+1)*(y2-y1+1)/2+((x2-x1+1)*(y2-y1+1)%2?(x1+y1)%2:0);
w2 = (x4-x3+1)*(y4-y3+1)/2+((x4-x3+1)*(y4-y3+1)%2?(x3+y3+1)%2:0);
b2 = (x4-x3+1)*(y4-y3+1)/2+((x4-x3+1)*(y4-y3+1)%2?(x3+y3)%2:0);
// cout<<wt<<' '<<bt<<' '<<w1<<' '<<b1<<' '<<w2<<' '<<b2<<' '<<we<<' '<<be<<endl;
cout<<wt-w2+(b1-be)<<' '<<m*n-(wt-w2+b1-be)<<endl;
}
return 0;
}