SCOI 数字立方体

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;
}
HASH的使用也不难,注意三维前缀和的维护。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值