题意:给出一个a,然后给出一行数字,数字的个数小于4000,数字的长度为len,这些数字组成一个n*n的方阵,方阵中 bij = si*sj ,问有多少矩阵的和是等于a的
思路:由这个方阵的特性 ,我们知道 每一行都是成比例的,也就是说 第i行 bik = si * sk, 就是si去乘给出的n个数, 而且矩阵又是连续的,那么意味的一个矩阵的和
sum = (si +.... +sj)*(sx + .....+ sy)
比如 1 2 3 4 5 比如 6 8
2 4 6 8 10 9 12 这个子矩阵的sum = (3 + 4)*(2 + 3)
3 6 9 12 15
4 8 12 15 20
由此我们可以统计出这一串数字组成连续的sum的大小以及个数并借助a = b*c来实现统计矩阵个数
那么相应的b出现的次数去乘c出现的次数,还要注意可以交换行和列组成
并且还要注意a=0的情况、
#include<cstring>
#include<cmath>
#include<cstdio>
const int qq=4005;
typedef long long ll;
int sum[qq];
ll vis[qq*10];
char num[qq];
int main()
{
int a;scanf("%d",&a);
scanf("%s", num+1);
ll n = strlen(num+1);
for(int i=1; i<=n; ++i){
sum[i] = sum[i-1] + num[i]-'0';
for(int j=0; j<i; ++j) //ͳ¼Æÿһ¶ÎÁ¬ÐøÊý×ֵĺ͡¢
vis[sum[i]-sum[j]]++;
}
ll ans=0;
if(a==0){
ans = vis[0]*(n*(n+1)-vis[0]);
printf("%lld\n", ans);
return 0;
}
for(int i=1; i*i<=a; ++i){
if(!vis[i]||a/i>qq*10) continue; //×¢Òâ±ðÔ½½çÁË¡¢
if(a%i==0) ans+=vis[i]*vis[a/i]*(i*i==a?1:2);
}
printf("%lld\n", ans);
return 0;
}