洛谷P3941 - 入阵曲 - 二维版k倍区间

2023-10-28 12:59

本文主要是介绍洛谷P3941 - 入阵曲 - 二维版k倍区间,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

链接:

https://www.luogu.org/problemnew/show/P3942


题目:

题目描述

丹青千秋酿,一醉解愁肠。
无悔少年枉,只愿壮志狂。小F很喜欢数学,但是到了高中以后数学总是考不好。有一天,他在数学课上发起了呆;他想起了过去的一年。一年前,当他初识算法竞赛的时候,觉得整个世界都焕然一新。这世界上怎么会有这么多奇妙的东西?曾经自己觉得难以解决的问题,被一个又一个算法轻松解决。小F当时暗自觉得,与自己的幼稚相比起来,还有好多要学习的呢。一年过去了,想想都还有点恍惚。他至今还能记得,某天晚上听着入阵曲,激动地睡不着觉,写题写到鸡鸣时分都兴奋不已。也许,这就是热血吧。

1

也就是在那个时候,小F学会了矩阵乘法。让两个矩阵乘几次就能算出斐波那契数列的第10100项,真是奇妙无比呢。不过,小F现在可不想手算矩阵乘法——他觉得好麻烦。取而代之的,是一个简单的小问题。他写写画画,画出了一个n×m的矩阵,每个格子里都有一个不超过k的正整数。
小F想问问你,这个矩阵里有多少个不同的子矩形中的数字之和是k的倍数?如果把一个子矩形用它的左上角和右下角描述为(x1,y1,x2,y2),其中x1≤x2,y1≤y2;
那么,我们认为两个子矩形是不同的,当且仅当他们以(x1,y1,x2,y2)表示时不同;也就是说,只要两个矩形以(x1,y1,x2,y2)表示时相同,就认为这两个矩形是同一个矩形,你应该在你的答案里只算一次。

输入

输入第一行,包含三个正整数n,m,k。输入接下来n行,每行包含m个正整数,第

输出

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

样例输入

2 3 2
1 2 1
2 1 2

样例输出

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)。

2


思路:

  k倍区间的二维版,i、j枚举子矩阵的上下边界,k枚举处理到了第几列,把i、j行之间,右边界是第k列的这个矩阵和取模统计一下,具体原理在链接里说的很详细, O(n3) O ( n 3 ) 可过。


实现:

#include <cstdio>
typedef long long ll;
const int maxn = 507;
ll ans = 0;
int cnt[int(1e6) + 7], num[maxn], sum[maxn][maxn];
int main() {int n, m, k, tmp;scanf("%d%d%d", &n, &m, &k);for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {scanf("%d", &tmp);sum[i][j] = sum[i - 1][j] + sum[i][j - 1] + tmp - sum[i - 1][j - 1];if (sum[i][j] >= k) sum[i][j] -= k;}}for (int i = 1; i <= n; i++) {for (int j = i; j <= n; j++) {cnt[0] = 1;for (int cur = 1; cur <= m; cur++) {num[cur] = (sum[j][cur] - sum[i - 1][cur]) % k;if (num[cur] < 0) num[cur] += k;ans += cnt[num[cur]];cnt[num[cur]]++;}for (int cur = 1; cur <= m; cur++) cnt[num[cur]] = 0;}}printf("%lld\n", ans);return 0;
}

这篇关于洛谷P3941 - 入阵曲 - 二维版k倍区间的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/293373

相关文章

C++中初始化二维数组的几种常见方法

《C++中初始化二维数组的几种常见方法》本文详细介绍了在C++中初始化二维数组的不同方式,包括静态初始化、循环、全部为零、部分初始化、std::array和std::vector,以及std::vec... 目录1. 静态初始化2. 使用循环初始化3. 全部初始化为零4. 部分初始化5. 使用 std::a

CSS3 最强二维布局系统之Grid 网格布局

《CSS3最强二维布局系统之Grid网格布局》CS3的Grid网格布局是目前最强的二维布局系统,可以同时对列和行进行处理,将网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局,本文介... 深入学习 css3 目前最强大的布局系统 Grid 网格布局Grid 网格布局的基本认识Grid 网

poj2576(二维背包)

题意:n个人分成两组,两组人数只差小于1 , 并且体重只差最小 对于人数要求恰好装满,对于体重要求尽量多,一开始没做出来,看了下解题,按照自己的感觉写,然后a了 状态转移方程:dp[i][j] = max(dp[i][j],dp[i-1][j-c[k]]+c[k]);其中i表示人数,j表示背包容量,k表示输入的体重的 代码如下: #include<iostream>#include<

hdu2159(二维背包)

这是我的第一道二维背包题,没想到自己一下子就A了,但是代码写的比较乱,下面的代码是我有重新修改的 状态转移:dp[i][j] = max(dp[i][j], dp[i-1][j-c[z]]+v[z]); 其中dp[i][j]表示,打了i个怪物,消耗j的耐力值,所得到的最大经验值 代码如下: #include<iostream>#include<algorithm>#include<

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :

HDU 2159 二维完全背包

FATE 最近xhd正在玩一款叫做FATE的游戏,为了得到极品装备,xhd在不停的杀怪做任务。久而久之xhd开始对杀怪产生的厌恶感,但又不得不通过杀怪来升完这最后一级。现在的问题是,xhd升掉最后一级还需n的经验值,xhd还留有m的忍耐度,每杀一个怪xhd会得到相应的经验,并减掉相应的忍耐度。当忍耐度降到0或者0以下时,xhd就不会玩这游戏。xhd还说了他最多只杀s只怪。请问他能

hdu4267区间统计

题意:给一些数,有两种操作,一种是在[a,b] 区间内,对(i - a)% k == 0 的加value,另一种操作是询问某个位置的值。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import

hdu4417区间统计

给你一个数列{An},然后有m次查询,每次查询一段区间 [l,r] <= h 的值的个数。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamRead

hdu3333区间统计

题目大意:求一个区间内不重复数字的和,例如1 1 1 3,区间[1,4]的和为4。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;

二维旋转公式

二维旋转公式 ros的tf工具包可以很方便的实现任意坐标系之间的坐标转换。但是,如果只是想简单的测试想法,而又不想编写过于庞杂的代码,考虑自己写二维旋转的函数。而与二维旋转问题对偶的另一个问题便是二维坐标系旋转变换。这两个问题的形式基本一样,只是旋转的角度相差一个负号。就是这个容易搞混,所以做个笔记,以备查用。 1. 二维旋转公式(算法) 而(此文只针对二维)旋转则是表示某一坐标点 ( x