数字立方体

 

题目描述

有一个立方体被分成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
using namespace std;
ll he[55][55][55];
int x[55][55][55],ge[1111111];
ll ji(int xx,int y,int a,int b,int h)
{
    return he[a][b][h]-he[xx-1][b][h]-he[a][y-1][h]+he[xx-1][y-1][h];
}
int main()
{
    int n;
    ll m;

    scanf("%d%lld",&n,&m);
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
        {
            for(int k=1; k<=n; k++)
            {
                scanf("%d",&x[i][j][k]);
            }
        }
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
        {
            for(int k=1; k<=n; k++)
            {
                he[i][j][k]=(long long)(x[i][j][k]+he[i-1][j][k]+he[i][j][k-1]+he[i][j-1][k]+he[i-1][j-1][k-1]-he[i-1][j-1][k]-he[i-1][j][k-1]-he[i][j-1][k-1])%m;

            }
        }

    int ans=0;
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
            for(int k=i; k<=n; k++)
                for(int o=j; o<=n; o++)
                {
                    ge[0]=1;
                    for(int h=1; h<=n; h++)
                    {
                        int ti=(int)(ji(i,j,k,o,h)%m+m)%m;
                        ge[ti]++;
                        ans+=ge[ti]-1;
                    }
                    for(int h=1; h<=n; h++)
                    {
                        int ti=(int)(ji(i,j,k,o,h)%m+m)%m;
                        ge[ti]--;
                    }
                }
    cout<<ans<<endl;
    return 0;
}

 

posted @ 2018-02-05 23:53  轻狂上邪  阅读(276)  评论(0)    收藏  举报