AtCoder Beginner Contest 164 D - Multiple of 2019 (数论规律同余)

整理的算法模板:ACM算法模板总结(分类详细版)

 

D - Multiple of 2019


Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 400400 points

Problem Statement

Given is a string SS consisting of digits from 1 through 9.

Find the number of pairs of integers (i,j)(i,j) (1≤i≤j≤|S|1≤i≤j≤|S|) that satisfy the following condition:

Condition: In base ten, the ii-th through jj-th characters of SS form an integer that is a multiple of 20192019.

Constraints

  • 1≤|S|≤2000001≤|S|≤200000
  • SS is a string consisting of digits from 1 through 9.

Input

Input is given from Standard Input in the following format:

SS

Output

Print the number of pairs of integers (i,j)(i,j) (1≤i≤j≤|S|1≤i≤j≤|S|) that satisfy the condition.


Sample Input 1 Copy

Copy

1817181712114

Sample Output 1 Copy

Copy

3

Three pairs - (1,5)(1,5), (5,9)(5,9), and (9,13)(9,13) - satisfy the condition.


Sample Input 2 Copy

Copy

14282668646

Sample Output 2 Copy

Copy

2

Sample Input 3 Copy

Copy

2119

Sample Output 3 Copy

Copy

0

 

题意:求一个至多长为20000的只包含1 ~ 9的字符串中有多少连续子串转为10进制后为2019的倍数。

思路:

如果两个数x,y 对同一个数(2019)取模的余数相同,我们称之为同余;x=2019*a+b  y=2019*c+b     那么x  y之间的差值一定是2019的整数倍;

从字符串右端开始往左扩展整数;

 每扩展一次就对x就行取模一次;如果出现两个数的余数相同就说明这两个数之间存在2019的倍数;所以用一个数组或者map记录之前每个余数出现的次数,每个x与之前同余的数间都可以构成2019的倍数,如果余数为0则x本身就可以作为2019的倍数,所以map[0]初始化为1。

#include 
using namespace std;
int sum[200005];
map mp;
int main()
{
    int ans=0;
    string s;
    cin >>s;
    mp[0]=1;
    int len=s.size(),x=0,cnt=1;
    for(int i=len-1;i>=0;i--)
    {
        x=((s[i]-'0')*cnt+x)%2019;
        ans+=mp[x];
        mp[x]++;
        cnt=cnt*10%2019;//注意这里是上面对x取模的时候也对cnt进行了取模
    }
    cout <

 

你可能感兴趣的:(基础算法——数论)