T2:
给定一个由数字(0-9)构成的字符串 s 。我们可以由此定义出 size(s) * size(s) 大小的矩阵 b ,其中 b[i][j] = s[i] * s[j] ;请问在这个矩阵 b 中,有多少子矩形满足其中的 b[i][j] 的和为另一个给定的数字 a 。
输入
10
12345
12345
输出
6
对 100% 的输入数据 :0≤a≤1000000000,size(s)≤4000 。
b矩阵为:
01 02 03 04 05 //发现 02 03 为(2+3)*(1+2)
02 04 06 08 10 04 06
03 06 09 12 15
04 08 12 16 20
05 10 15 20 25
f[i][j]为s第i为到第j为的和
子矩阵的和为 发 某个f[i][j]* 某个f[i][j]
先求f[i][j] ,统计f[i][j]出现的次数;
ans+=t(f[i][j])*(aim/f[i][j]) // aim为a
#include<bits/stdc++.h>
using namespace std;
int q[40005],aim;
int f[4005][4005];
int t[1000005]; //9*4000 f[i][j]最大为36000;
bool ex[1000005];
int hash(int k){
int mod=1e6+7,i;
i=(k*23)%mod;
return i;
}
int main(){
// freopen("rect.in","r",stdin);
// freopen("rect.out","w",stdout);
memset(q,0,sizeof(q));
memset(f,0,sizeof(f));
memset(t,0,sizeof(t));
scanf("%d",&aim);
char st[40005];
scanf("%s",st+1);
int len=strlen(st+1);
for(int i=1;i<=len;++i) q[i]=st[i]-'0',f[i][i]=q[i];
for(int i=1;i<=len;++i)
for(int j=i+1;j<=len;++j)
f[i][j]=f[i][j-1]+q[j];
for(int i=1;i<=len;++i)
for(int j=i;j<=len;++j){
if(f[i][j]==0) t[0]++;
if(f[i][j]>0)
if(aim%f[i][j]==0)
t[hash(f[i][j])]+=1;
}
long long ans=0;
if(aim!=0)
for(int i=1;i<=aim;++i){
if(aim%i==0){
int k=aim/i;
ans=ans+(long long)t[hash(i)]*t[hash(k)];
}
}
else {
ans=ans+(long long)t[0]*len*(len+1)-(long long)t[0]*t[0];//0出现的次数*总数()*2- 0出现的次数*0出现的次数
//总数为len*(len+1)/2
cout<<ans;
return 0;
}
cout<<ans;
return 0;
}