#P2479. 倍数子串(timestr)

倍数子串(timestr)

Description


【问题描述】
Jimmy 对数字有着异于常人的热爱。有一天,他随便写出来一个数字——04320,然后开始对着这个数字写写画画。他发现,从这个数字中随便选出连续的一段(Jimmy 把这个称为 连续子串),有可能是 4 的倍数,例如 4,04,32,432 等;也有可能是 5 的倍数,例如 20,320 等。
Jimmy 的老师恰好路过此处,他向正沉迷于自己发现的 Jimmy 提了一个有趣的问题——给定一个指定的数字串,请问有多少 连续子串 是 4 或者 5 的倍数呢?
老师还特别提醒他:
1. 连续子串 的开头可以是 0;
2. 两个 连续子串 只要是从数字串中的不同位置选出来的,它们就算是不同的;
3. 如果一个 连续子串 同时是 4 和 5 的倍数,应当只被计算一次哦!

【输入格式】
一行一个数字串,长度为 n。

【输出格式】
一行一个整数,表示所有的连续子串中,为 4 或者 5 的倍数的数量。

【样例 1 输入】
04320

【样例 1 输出】
11

【样例 1 解释】
所有满足题意的连续子串分别为:0,04,0432,04320,4,432,4320,32,320,20,0。
其中有两个相同的 0,这是因为它们是从数字串中的不同位置选出来的(一个在开头处,一
个在结尾处)。

【样例 2 输入】
2000

【样例 2 输出】
9

【测试点约束】
对于 10% 的数据,保证 $n = 1$。
对于 60% 的数据,保证 $1 ≤ n ≤ 10^3$。
对于 100% 的数据,保证 $1 ≤ n ≤ 10^6$。

Hint

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
long long ans;
char s[N];
int main()
{
	scanf("%s",s+1);
	int len=strlen(s+1);
	for(int i=1;i<=len;i++)s[i]=s[i]-'0';
	long long ans=0;
	for(int i=1;i<=len;i++)if(s[i]%4==0||s[i]%5==0)ans++;
	for(int i=2;i<=len;i++)if((s[i-1]*10+s[i])%4==0||s[i]%5==0)ans=ans+i-1;
	printf("%lld",ans);
	return 0;
}