Codeforces Round#524(Div.2)C-Masha and two friends(数学+思考+統計+クラウドAC)


タイトルリンク:http://codeforces.com/contest/1080/problem/C
タイトル:白黒の碁盤の中で、左下の位置は白です.2回操作する機会があり、初めて矩形を選択し、それをすべて白く塗ります.2回目に再び矩形を選択し、すべて黒く塗ります.最後に白と黒の数を聞きます.
私たちは簡単に発見します.四角形の四角形の数を偶数として選択すると、黒と白の四角形の数は同じになります.
奇数の場合は、次の2つのケースがあります.
1つ目は左下の格字が白いので、この矩形の白い格子の個数は黒い格子の個数より1つ多いです.
一つ目は左下の格字が黒で、この矩形の黒い格子の個数は白い格子の個数より一つ多い.
だから、最初の白と黒の個数を統計することができます.
そして白塗りの場合、黒が何個少なく、白が何個多いかを判断します.黒の少ない個数は白の多い個数です
次に黒塗りの場合、白がどれだけ少なく、黒がどれだけ多いかを判断します.白の少ない個数は黒の多い個数です
ここで,2回選択した矩形が交差していると判断し,交差しなければ答えを出力すればよい.
交わると、黒に相当する個数が少なくなります.もともと黒塗りの時の格字白黒が半分になると仮定していたので、その中の1枚の領域はすべて白だった.黒の個数を少なく計算したことに相当しますだから、黒い格子の数に交差する領域の白い格子の数を加える必要があります.もちろん、白い格子もこんなに減らさなければなりません.
うん、これで考えは終わりだ.
そして出てこないわけじゃない!!!バグが多すぎます.!!!
雲!A ! C !
他の人のコードを入れます.
#include 
#define LL long long
using namespace std;

LL n,m,B,W;
LL X1,Y1,X2,Y2,X3,Y3,X4,Y4;
void col(LL lx,LL ly,LL rx,LL ry,bool flag) {
    LL N=ry-ly+1LL, M=rx-lx+1LL, b, w;

    if((lx+ly)%2LL) //         
        w=N*M/2LL, b=w+(N*M%2LL);
    else //      
        b=N*M/2LL, w=b+(N*M%2LL);

    if(flag) W+=b, B-=b; //   
    else B+=w, W-=w; //   
}
void cut(LL lx,LL ly,LL rx,LL ry) {
    if(lx>rx || ly>ry) return; //      
    if(rxX4 || ly>Y4) {
        col(lx,ly,rx,ry,1); return;
    } //                      
    if(lxX4) cut(X4+1LL,ly,rx,ry), rx=X4;
    if(lyY4) cut(lx,Y4+1LL,rx,ry), ry=Y4;
}
int main()
{
    int t; scanf("%d",&t);
    while(t--) {
        scanf("%I64d%I64d",&n,&m);
        B=n*m/2LL, W=B+(n*m%2LL);
        scanf("%I64d%I64d%I64d%I64d",&X1,&Y1,&X2,&Y2);
        scanf("%I64d%I64d%I64d%I64d",&X3,&Y3,&X4,&Y4);
        cut(X1,Y1,X2,Y2);
        col(X3,Y3,X4,Y4,0);
        printf("%I64d %I64d
",W,B); } return 0; }