题解
- 我们发现b[i][j]=s[i]*s[j]
- 那么考虑一下如果i或j相等是,行或列会有共同的公因数
- 可以得到a=sum[x1...x2]*sum[y1...y2]
- 那么sum[x1...x2]和sum[y1...y2]都是a的倍数
- 考虑枚举sum[x1...x2]的值
- 可以用前缀和,用num[i]记录出现i的次数
- 那么就可以枚举sum[x1...x2]
- 那么对于答案的贡献就是num[a/sum[x1...x2]]*num[sum[x1...x2]]
- 你以为就这样就可以A了吗。。。。。
- 考虑一下a为0时
- sum[y1...y2]可以取任意值
代码
1 #include<cstdio>
2 #include<iostream>
3 #include<cmath>
4 #include<cstring>
5 using namespace std;
6 long long x,ans,len,a[40010],num[40010],k;
7 char s[40100];
8 int main()
9 {
10 scanf("%lld",&x); scanf("%s",s+1);
11 len=strlen(s+1);
12 for (int i=1;i<=len;i++) a[i]=a[i-1]+s[i]-'0';
13 for (int i=1;i<=len;i++)
14 for (int j=i;j<=len;j++)
15 num[a[j]-a[i-1]]++;
16 if (x!=0)
17 {
18 for (int i=1;i<=len;i++)
19 for (int j=i;j<=len;j++)
20 {
21 k=a[j]-a[i-1];
22 if (!k) continue;
23 if (x%k!=0) continue;
24 if (x/k>36000) continue;
25 ans+=num[x/k];
26 }
27 }
28 else
29 {
30 for (int i=1;i<=len;i++)
31 for (int j=i;j<=len;j++)
32 {
33 k=a[j]-a[i-1];
34 if (k==0) ans+=len*(len+1)/2; else ans+=num[0];
35 }
36 }
37 printf("%lld",ans);
38 return 0;
39 }