4123: 数字立方体
时间限制: 5 Sec 内存限制: 128 MB
提交: 33 解决: 16
题目描述
有一个立方体被分成n*n*n的单位,坐标用(X,Y,Z)表示(1<=X,Y,Z<=n<=40)。每个单位立方体内有一个绝对值不超过1e9的整数。统计有多少个子立方体的所有数之和是m的倍数。子立方体即满足x1<=X<=x2, y1<=Y<=y2, z1<=Z<=z2的所有单位立方体集合,其中1<=x1,x2,y1,y2,z1,z2<=n。
输入
第一行有两个整数n, m,表示立方体的边长和作除数的正整数。以下n*n行,每行有n个整数。首先是X=1, Y=1的n个单位立方体,然后是X=1, Y=2的n个, …最后是X=n, Y=n-1的n个和X=n和Y=n的n个,共n3个整数。( 1<=m<=1000000)
输出
仅包含一个数,即所有整数和为m的倍数的子立方体的个数。
样例输入
2 5
1 2
3 4
5 6
7 8
样例输出
5
#include <bits/stdc++.h>
#define ll long long
#define rep(i,s,t) for (int i=s;i<=t;++i)
using namespace std;
const int mx = 41;
const int M = 1000000;
ll sum[mx][mx][mx];
int n,m,ans,d[mx][mx][mx],Hash[M];
ll fun(int lux,int luy,int rdx,int rdy,int h) {
return sum[rdx][rdy][h]-sum[lux-1][luy-1][0]-sum[lux-1][rdy][h]-sum[rdx][luy-1][h]-sum[rdx][rdy][0]+sum[lux-1][luy-1][h]+sum[lux-1][rdy][0]+sum[rdx][luy-1][0];
}
int read() {
int f=1;
char c=getchar();
while (!isdigit(c)&&c!='-') c=getchar();
if (c=='-') f=-1,c=getchar();
int k = 0;
while (isdigit(c)) k=k*10+c-48,c=getchar();
return f*k;
}
int main()
{
n=read();
m=read();
rep(i,1,n) rep(j,1,n) rep(k,1,n) {
d[i][j][k]=read();
sum[i][j][k]=d[i][j][k]+sum[i-1][j-1][k-1]+sum[i][j][k-1]+sum[i][j-1][k]+sum[i-1][j][k]-sum[i-1][j-1][k]-sum[i-1][j][k-1]-sum[i][j-1][k-1];
}
rep(lux,1,n) rep(luy,1,n)
rep(rdx,lux,n) rep(rdy,luy,n) {
Hash[0]=1;
rep(h,1,n) {
int t = fun(lux,luy,rdx,rdy,h)%m;
Hash[t]++;
if (Hash[t]>1) ans+=Hash[t]-1;
}
rep(h,1,n) Hash[fun(lux,luy,rdx,rdy,h)%m]--;
}
printf("%d\n",ans);
return 0;
}