http://blog.csdn.net/qq_36312502/article/details/78453922
https://www.luogu.org/problemnew/show/P3941
丹青千秋酿,一醉解愁肠。
无悔少年枉,只愿壮志狂。
我不管,今天晚上通宵(听入阵曲和一生所爱)学图论(huashui)。
这个吗,有点脑洞。最开始时n6方,普通二维前缀和压成n4方,现在这样压成n3方
就是让你求子矩阵的数字和,我们可以一行一行的处理,不需要整个枚举一遍。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<stack>
using namespace std;
typedef long long ll;
ll sum[1010][1010],sum2[1010];
ll a[1010][1010];
ll n,m,mod,ans;
ll cnt[1010000];
int main()
{
scanf("%lld%lld%lld",&n,&m,&mod);
for(ll i=1;i<=n;i++)
for(ll j=1;j<=m;j++)
{
scanf("%lld",&a[i][j]);
sum[i][j]=sum[i][j-1]+a[i][j]+sum[i-1][j]-sum[i-1][j-1];
sum[i][j]%=mod;
}
for(ll i=0;i<n;i++)
for(ll j=i+1;j<=n;j++)
{
cnt[0]=1;
for(ll k=1;k<=m;k++)
{
sum2[k]=sum[j][k]-sum[i][k];sum2[k]%=mod;
while(sum2[k]<0) sum2[k]+=mod;
ans+=cnt[sum2[k]];
cnt[sum2[k]]++;
}
for(ll k=1;k<=m;k++) cnt[sum2[k]]=0;
}
cout<<ans;
return 0;
}