Rocket323 loves math very much. One day,
Rocket323 got a number string. He could choose some consecutive digits from the string to form a number.
Rocket323 loves 64 very much, so he wanted to know how many ways can he choose from the string so the number he got multiples of 64 ?
A number cannot have leading zeros. For example, 0, 64, 6464, 128 are numbers which multiple of 64 , but 12, 064, 00, 1234 are not.
A number cannot have leading zeros. For example, 0, 64, 6464, 128 are numbers which multiple of 64 , but 12, 064, 00, 1234 are not.
Input
Multiple cases, in each test cases there is only one line consist a number string.
Length of the string is less than 3 * 10^5 .
Huge Input , scanf is recommended.
Length of the string is less than 3 * 10^5 .
Huge Input , scanf is recommended.
Output
Print the number of ways
Rocket323 can choose some consecutive digits to form a number which multiples of 64.
Sample Input
64064
Sample Output
5
Hint
There are five
substrings which multiples of 64.
[64]064
640[64]
64[0]64
[64064]
[640]64
[64]064
640[64]
64[0]64
[64064]
[640]64
这边很巧妙,1000000是64的倍数,那么长为3e5的字符串,其实就可以枚举长度为6的后缀,如果后缀是64的倍数,那么前面不管是什么都能被64整除。
so结果就很容易处理了。只要先暴力长度为连续k(1-6)的数...
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 3e5+10;
char s[N];
int num[N],pre[N];
int main()
{
int i,j,len,k,tem;
long long ans;
while(scanf("%s",s+1)!=EOF) {
ans=0;
len=strlen(s+1);
pre[0]=0;
for(i=1;i<=len;i++) {
num[i]=s[i]-'0';
if(num[i]) pre[i]=pre[i-1];
else pre[i]=pre[i-1]+1;
}
for(k=1;k<7;k++) {
for(i=1;i<=len;i++) {
tem=0;
if(num[i]==0) continue;
if(i+k-1>len) break;
for(j=i;j<i+k;j++) {
tem=tem*10+num[j];
}
if(tem%64==0) ans++;
}
}
for(i=1;i<=len;i++) {
tem=0;
if(i+5>len) break;
for(j=i;j<i+6;j++) {
tem=tem*10+num[j];
}
if(tem%64==0) ans+=i-1-pre[i-1];
}
ans+=pre[len];
printf("%lld\n",ans);
}
return 0;
}