2018-11-27 Gym-101991D丨暴力丨离散化

本文解析了Gym-101991D题目的解决方案,该题目要求在给定的n*m黑巧克力网格中,找出所有前缀矩阵中白块数量为奇数的情况。通过坐标离散化和前缀矩阵的构建,算法能够高效地计算出满足条件的矩阵个数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Gym-101991D

题意

给n*m的黑巧克力,其中k块是白的,输入白块的坐标,求满足条件的前缀矩阵的个数,条件是前缀矩阵中的白块个数为奇数。

思路

先坐标离散化,针对白块求前缀矩阵,然后遍历每块前缀,如果前缀是奇数,那么这个 ans 的增量应该是,到下一个最近的白块之间的矩阵的单元个数(因为在这之间的前缀白块个数不会发生改变。)

细节上再稍微注意一些即可。我的代码里sum只记奇偶状态,用异或计算,优化了一下空间。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e3+5;
const int INF = 0x3f3f3f3f;
int T,n,m,k;
int x[MAXN],y[MAXN],xx[MAXN],yy[MAXN];
bool sum[MAXN][MAXN];

int main(){
    freopen("dull.in","r",stdin);
    scanf("%d",&T);
    while(T--){
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<k;i++){
            scanf("%d%d",x+i,y+i);
            xx[i]=x[i];
            yy[i]=y[i];
        }
        sort(xx,xx+k);
        sort(yy,yy+k);
        int nn=unique(xx,xx+k)-xx;
        int mm=unique(yy,yy+k)-yy;
        xx[nn]=n+1;
        yy[mm]=m+1;

        for(int i=0;i<nn;i++)
        for(int j=0;j<mm;j++)
            sum[i][j]=false;

        for(int i=0,ix,iy;i<k;i++){
            ix=lower_bound(xx,xx+nn,x[i])-xx;
            iy=lower_bound(yy,yy+mm,y[i])-yy;
            sum[ix][iy]^=1;
        }

        for(int i=0;i<nn;i++)
        for(int j=1;j<mm;j++)
            sum[i][j]^=sum[i][j-1];
        for(int i=1;i<nn;i++)
        for(int j=0;j<mm;j++)
            sum[i][j]^=sum[i-1][j];

        ll ans=0;
        for(int i=0;i<nn;i++)
        for(int j=0;j<mm;j++)
            if(sum[i][j])
                ans+=(xx[i+1]-xx[i])*1ll*(yy[j+1]-yy[j]);
        printf("%lld %lld\n",ans,1ll*n*m-ans);
    }
    return 0;
}
/*
3
3 3 0
3 3 1
2 2
5 5 5
1 5
2 1
3 3
4 2
5 4
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值