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 <bits/stdc++.h>
using namespace std;
int sum[200005];
map<int,int> 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 <<ans<<endl;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章