机房模拟题解

7月份的机房内模拟考,虽然题不是非常难,但是考得也不太好呢.....

T1 入阵曲

给你一个矩阵和一个常数k,问你有多少个子矩阵的和是k的倍数

数据范围:矩阵长宽不超过400,k<=1e6

我们可以首先想到n^4的做法,先记录二维的前缀和,然后枚举矩形的端点坐标,然后枚举其长和宽,这样可以拿到60分,再加上有15分特殊数据,可以靠暴力拿到75分以上

然后我们可以大概猜到正解是n^2logn或者是n^3,由于矩阵二分起来很不方便,我们就考虑n^3的做法

我们注意到,因为要是k的倍数,所以说只要模k为0的子矩阵就满足要求,因此我们只需要在前缀和中存下子矩阵的和对k的模数即可,我们又可以注意到,如果有一个矩阵和一个大矩阵模k意义下同余,则说明大矩阵减去小矩阵一定是k的倍数,如下图

于是我们只需要枚举起点坐标和长度或者宽度,然后用一个桶来存每一个子矩阵取余过后的数的数量,就可以n^3(其实是n*m^2或者m*n^2)处理这个问题了

代码实现如下

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
const int MAXN=405;
typedef long long ll;
ll ans;
int n,m,k;
int a[MAXN][MAXN];
ll s[MAXN][MAXN];
ll b[MAXN];
int t[1000005];
int vis[1000005],cnt;
int v[MAXN];
int vnum; 
void work(int x,int y)
{
    cnt++;
    vnum
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值