Codeforces 1080C. Masha and two friends

给你一个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;
}

猜你喜欢

转载自blog.csdn.net/winhcc/article/details/84453442