题目
给定一个由数字(0-9)构成的字符串s。我们可以由此定义出size(s) * size(s) 大
小的矩阵b,其中b[i][j] = s[i] * s[j];请问在这个矩阵b中,有多少子矩形满足其中的b[i][j]的和为另一个给定的数字a。
分析
Size(s)≤ 4000,注意到 a = sum[x1..x2] * sum[y1..y2],那么 sum[x1..x2]和sum[y1..y2]都要是 a 的约数,不失一般性,我们枚举 sum[x1..x2]的值,那么我们所关心的就是符合 sum[x1..x2]这样的和符合 sum[y1..y2] = a / sum[x1..x2]那样的值分别有多少个,把这两个数乘起来进行累加,即为答案;但是,a 可以取到 0,上述方法即不成立,所以需要特殊考虑;当sum[x1..x2] = 0 时,sum[y1..y2]可以为任意值;
程序
#include<cstring>
#include<iostream>
using namespace std;
int n,l;
int a[50005],sum[50005];
long long ans;
char s[50005];
int main(){
cin>>n;
cin>>s;
l=strlen(s);
for(int i=1;i<=l;i++)
a[i]=a[i-1]+s[i-1]-'0';
for(int i=1;i<=l;i++)
for(int j=i;j<=l;j++)
sum[a[j]-a[i-1]]++;
if (n!=0)
for(int i=1;i<=l;i++)
for(int j=i;j<=l;j++){
int t=a[j]-a[i-1];
if (t==0) continue;
if (n%t!=0) continue;
if (n/t>50005) continue;
ans+=sum[n/t];
}
else
for(int i=1;i<=l;i++)
for(int j=i;j<=l;j++){
int t=a[j]-a[i-1];
if(t==0) ans+=l*(l+1)/2;
else ans+=sum[0];
}
cout<<ans<<endl;
return 0;
}