感谢小宇哥耐心的指导,感觉自己脑子真是不转
题意:
给定一串字符串,按要求构成一个矩阵B bij=si*sj。
按题意会得到 加入矩阵c满足和为a c1+c2+c3+c4=s1*s2+s1*s1+s2*s1+s2*s2=(s1+s2)*(s1+s2)
那么只需要记录行列的区间和就好了(理解了半天,还多亏小宇哥告诉。。)
在对行列记录时候,行和列等价,只有在行区间*列区间==a时候,满足题意。
两个数字记录与根号的关系
注意特判a=0
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <cstring>
#include <string>
#include <cmath>
using namespace std;
long long row[100005];
long long a[4005][4005];
char s[5005];
long long ans=0;
long long n,len;
int main()
{
cin>>n;
scanf("%s",s);
len=strlen(s);
for(int i=0;s[i];i++)
s[i]=s[i]-'0';
long long res=0;
double aim=sqrt(n);
if(n==0)
{
long long zero=0,r=0;
for(int i=0;i<len;i++)
{
res=0;
for(int j=i;j<len;j++)
{
res+=s[j];
if(res==0)
{
zero++;
}
else
r++;
}
}
ans=zero*zero+zero*r*2;
cout<<ans<<endl;
return 0;
}
for(int i=0;i<len;i++)
{
res=0;
for(int j=i;j<len;j++)
{
res+=s[j];
if(res!=0&&n%res==0&&res<=aim )
{
row[res]++;
}
if(res>aim)
break;
}
}
for(int i=0;i<len;i++)
{
res=0;
for(int j=i;j<len;j++)
{
res+=s[j];
if(res!=0&&n%res==0&&res>=aim)
{
long long tep=n/res;
if(tep*tep==n)
{
ans+=row[tep];
}
else
{
ans+=2*row[tep];
}
if(res>n)
break;
}
}
}
cout<<ans<<endl;
return 0;
}
/*
16
439873893693495623498263984765
*/