丹青千秋酿,一醉解愁肠。

无悔少年枉,只愿壮志狂

题目

题目描述

小 F 很喜欢数学,但是到了高中以后数学总是考不好。

有一天,他在数学课上发起了呆;他想起了过去的一年。一年前,当他初识算法竞赛的 时候,觉得整个世界都焕然一新。这世界上怎么会有这么多奇妙的东西?曾经自己觉得难以 解决的问题,被一个又一个算法轻松解决。

小 F 当时暗自觉得,与自己的幼稚相比起来,还有好多要学习的呢。

一年过去了,想想都还有点恍惚。

他至今还能记得,某天晚上听着入阵曲,激动地睡不着觉,写题写到鸡鸣时分都兴奋不 已。也许,这就是热血吧。

也就是在那个时候,小 F 学会了矩阵乘法。让两个矩阵乘几次就能算出斐波那契数列的 第 $10^{100}$ 项,真是奇妙无比呢。

不过,小 F 现在可不想手算矩阵乘法——他觉得好麻烦。取而代之的,是一个简单的小 问题。他写写画画,画出了一个 $n×m$的矩阵,每个格子里都有一个不超过 k 的正整数。

小 F 想问问你,这个矩阵里有多少个不同的子矩形中的数字之和是 k 的倍数? 如果把一个子矩形用它的左上角和右下角描述为 $(x_1,y_1,x_2,y_2)$,其中$x_1 \le x_2,y_1 \le y_2$ ​:那么,我们认为两个子矩形是不同的,当且仅当他们以 $(x_1,y_1,x_2,y_2)$ 表示时不同;也就是 说,只要两个矩形以 $(x_1,y_1,x_2,y_2)$表示时相同,就认为这两个矩形是同一个矩形,你应该 在你的答案里只算一次。

输入输出格式

输入格式:

从标准输入中读入数据。

输入第一行,包含三个正整数 n,m,k;

输入接下来 n 行,每行包含 m 个正整数,第 i 行第 j 列表示矩阵中第 i 行第 j 列 中所填的正整数 a_{i,j}。

输出格式:

输出到标准输出中。

输入一行一个非负整数,表示你的答案。

样例

Sample Input

2 3 2
1 2 1
2 1 2

Sample Output

6

数据范围与说明

样例说明
这些矩形是符合要求的:
(1, 1, 1, 3),(1, 1, 2, 2),(1, 2, 1, 2),(1, 2, 2, 3),(2, 1, 2, 1),(2, 3, 2, 3)

数据范围

题解

分析

这道题上来先来一个 $O(N^4)$ 的暴力,使用前缀和;

但是,我们会发现,在枚举每个子矩阵时,有的部分是重复计算的

  • i,j枚举子矩阵的上下边界,o枚举我们处理到了第几列,把i、j行之间,右边界是第o列的矩阵压成一个数,之后枚举统计。

  • 我们要把 i 到 j 的矩阵变成一行,然后就可以做 (K倍区间) 详细的可以看

链接 http://blog.csdn.net/qq_35776409/article/details/78226120

具体原理:

对于任意一段区间[l,r]的和就是sum[r]-sum[l-1].

(sum[r]-sum[l-1])%k 保证了[l,r]这段区间要么%k等于0 要么比k小.

等于0这表示了正好是k的倍数 然后通过前缀和相同的数据来判断出剩下的k的倍数:$(sum[r]-sum[l-1])%k == 0$.

变形后就是:sum[r]%k==sum[l-1]%k

代码

#include<iostream>
#include<cstring>
#include<cstdio> using namespace std;
#define MAXN 410
typedef long long LL;
int a[MAXN][MAXN],b[MAXN],cnt[1000005];
LL sum[MAXN][MAXN];
inline void read(int &x){
x=0; int f=1; char c=getchar();
while(c>'9'||c<'0'){ if(c=='-')f=-1; c=getchar(); }
while(c>='0'&&c<='9'){ x=x*10+c-'0'; c=getchar(); } x*=f;
} LL Ans = 0;
int main(){
freopen("rally.in","r",stdin);
freopen("rally.out","w",stdout);
int n,m,Mod;
read(n),read(m),read(Mod);
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j){
read(a[i][j]);
sum[i][j] = (sum[i-1][j] + a[i][j] + sum[i][j-1] - sum[i-1][j-1]);
if(sum[i][j] >= Mod) sum[i][j] -= Mod;
}
for(int i=0; i<n; ++i)
for(int j=i+1; j<=n; ++j){
cnt[0] = 1;
for(int k=1; k<=m; ++k) {
b[k] = (sum[j][k] - sum[i][k] ) % Mod;
if(b[k] < 0) b[k] += Mod;
Ans += cnt[b[k]];
++cnt[b[k]];
}
for(int k=1; k<=m; ++k) cnt[b[k]] = 0;
}
printf("%lld\n",Ans);
fclose(stdin); fclose(stdout);
return 0;
}

  

【题解】入阵曲 luogu3941 前缀和 压维的更多相关文章

  1. BZOJ 2101 [Usaco2010 Dec]Treasure Chest 藏宝箱:区间dp 博弈【两种表示方法】【压维】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2101 题意: 共有n枚金币,第i枚金币的价值是w[i]. 把金币排成一条直线,Bessie ...

  2. [luogu]P3941 入阵曲[前缀和][压行]

    [luogu]P3941 入阵曲 题目描述 小 F 很喜欢数学,但是到了高中以后数学总是考不好. 有一天,他在数学课上发起了呆:他想起了过去的一年.一年前,当他初识算法竞赛的 时候,觉得整个世界都焕然 ...

  3. [洛谷P3941]:入阵曲(前缀和+桶)

    题目传送门 题目背景 丹青千秋酿,一醉解愁肠.无悔少年枉,只愿壮志狂. 题目描述 小$F$很喜欢数学,但是到了高中以后数学总是考不好.有一天,他在数学课上发起了呆:他想起了过去的一年.一年前,当他初识 ...

  4. Luogu P3941 入阵曲【前缀和】By cellur925

    题目传送门 题目大意:给你一个\(n\)*\(m\)的矩阵,每个位置都有一个数,求有多少不同的子矩阵使得矩阵内所有数的和是\(k\)的倍数. 数据范围给的非常友好233,期望得到的暴力分:75分.前1 ...

  5. BZOJ1177 [Apio2009]Oil 二维前缀和 二维前缀最值

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1177 题意概括 在一个n*m的矩阵中,每一个位置一个数字. 现在让你选出3个k*k的矩阵,它们互不 ...

  6. 前缀和&二维前缀和

    我们知道,数组上的前缀和S[i]=S[i-1]+a[i] 那么,怎样求二维前缀和呢? 二维前缀和: 绿色点的前缀和就是黄色.红色.灰色和绿色的点权和 怎样计算? s[i][j]=s[i-1][j]+s ...

  7. Codeforces 1262E Arson In Berland Forest(二维前缀和+二维差分+二分)

     题意是需要求最大的扩散时间,最后输出的是一开始的火源点,那么我们比较容易想到的是二分找最大值,但是我们在这满足这样的点的时候可以发现,在当前扩散时间k下,以这个点为中心的(2k+1)2的正方形块内必 ...

  8. LeetCode Continuous Subarray Sum 题解 同余前缀和 Hash表

    文章目录 题意 思路 特殊情况k=0 Source Code 1 Source Code 2 题意 给定一个数组和一个整数k,返回是否存在一个长度至少为2的连续子数组的和为k的倍数. 思路 和上一篇博 ...

  9. Codeforces 1093G题解(线段树维护k维空间最大曼哈顿距离)

    题意是,给出n个k维空间下的点,然后q次操作,每次操作要么修改其中一个点的坐标,要么查询下标为[l,r]区间中所有点中两点的最大曼哈顿距离. 思路:参考blog:https://blog.csdn.n ...

随机推荐

  1. 5分钟,教你用Python每天跟女朋友说1000遍土味情话!

  2. OJ最大值最小化问题(分发书本)

    该类问题通用描述: 有n个物体,每个物体都有一个权值V[i],现在将n个物体连续分成m个部分,m个部分有一个部分会拿到最多的权值v.求所有分配方式中最小的v. 典型题目: 分发书本,宠物屋涂色等. 问 ...

  3. Unity动态构建mesh绘制多边形算法流程分析和实践

    前言 先说一下,写这篇博文的动机,原文的博主代码写的十分潇洒,以至于代码说明和注释都没有,最近恰逢看到,所以以此博文来分析其中的算法和流程 参考博文:https://blog.csdn.net/lin ...

  4. 游戏中的2D OBB碰撞模型的碰撞算法介绍和实践

    前言 上一篇博文说道,射线与场景中模型上的所有三角形求交时,会大幅度影响效率且花费比较多的时间,因此会采取使用包围盒的形式,进行一个加速求交.在此文中介绍OBB碰撞模型的碰撞算法 OBB的碰撞模型 有 ...

  5. JavaI/O流汇总

    Java中常见流学习汇总 流的含义 流在Java中是指计算中流动的缓冲区. 从外部设备流向中央处理器的数据流成为"输入流",反之成为"输出流". 字符流和字节流 ...

  6. 那些好用的 VS Code 插件,究竟是如何提高编码效率的?

    在上一篇文章中我们已经对 vscode 插件有了一个初步的认识与了解了,接下去我们就要"揭秘"一下市面上那些好用的 vscode 插件究竟是如何帮我们提高工作效率的. 本文首发于「 ...

  7. Spark大数据处理框架入门(单机版)

    导读 引言 环境准备 安装步骤 1.下载地址 2.开始下载 3.解压spark 4.配置环境变量 5.配置 spark-env.sh 6.启动spark服务 7.测试spark stay hungry ...

  8. mysql基本命令(增,查,改,删)

    from oldboy egon

  9. 攻防世界(九)PHP2

    攻防世界系列:PHP2  1.打开什么信息也没有. 尝试各种首页index.php index.html 加 [F12]没有结果,最后发现是index.phps .phps文件是什么? phps文件就 ...

  10. 11.14 mii-tool:管理网络接口的状态

    mii-tool命令用于查看.管理网络接口,默认情况下网卡的状态是自动协商的,但是有时也会出现不正常的情况,可以使用mii-tool进行调整. mii-tool [option] [interface ...