AtCoder Beginner Contest - Multiple of 2019

Authors: Maggie Liu, Brad Ma, Mohammad Nour Massri, David Zhang

Official Analysis

Explanation

In order to store sections of the string, we can make a suffix array SS, such that:

Si=sn+10sn1+100sn2+...+10nisi{S_i = s_n + 10*s_{n-1} +100*s_{n-2} + ... + {10^{n-i}} * s_{i}}

For example, if our string was 12341234 and the modulus was 33 (instead of 20192019 for the sake of simplicity), the suffix array would be

[1234,234,34,4,0][1234, 234, 34, 4, 0]

Keep in mind, that an empty suffix with is also considered.

This is useful because we can access any substring in O(1)\mathcal{O}(1) time through a range query. So if S0=1234{S_0} = 1234 and S3=4{S_3=4}, this means S0S3=123101{S_0}-{S_3} = 123 * {10^1} or 12301230.

It also means that if both S0(mod{S_0}(mod M)=M)= S3(mod{S_3}(mod M)M) (both suffixes have the same remainders), subtracting would lead to S0(mod{S_0}(mod M)M)- S3(mod{S_3}(mod M)=0M)=0, meaning a substring that is divisible by 20192019.

So with 12341234, S0S3=1234(mod{S_0-{S_3}=1234(mod} 3)4(mod3)-4(mod 3)=11=03)=1-1=0. Because they substract to zero, it means the substring from index 00 to 22 leads to a number divisible by the modulus. (The substring is 123123 which is divisble by 3).

However, we would still need to go through every pair of possible suffixes (i,j)(i, j) which would be O(N2)\mathcal{O}(N^2).

Instead, we do not need to know which suffix has a certain remainder, but rather how many suffixes have that certain remainder.

To elaborate, we can take (NK){N \choose K}, and choose 2 numbers that are divisible by the same remainder of 2019, where N=N= the amount of times a certain remainder occurs, and K=K= 2 (because we are picking 2 indicies ii and jj).

Therefore, our answer is the counts of all the remainders in an array from 0...20180...2018 and (N2){N \choose 2}.

So in our example with 12341234, our new array would look like this:

[2,3,0][2, 3, 0]

Where each index represents the count of a certain remainder.

  • There are 22 suffixes with a remainder of 00 when dividing by 33, [234,0][234, 0]
  • There are 33 suffixes with a remainder of 11 when dividing by 33, [1234,34,4][1234, 34, 4]
  • And there are no suffixes with a remainder of 22

So, the sum of all of these numbers would be (22)+(32)=1+3=4{2 \choose 2} + {3 \choose 2}=1+3=4

If N<KN<K, it should be 00, since there aren't enough suffixes that can make a pair.

Implementation

A prefix array can be utilized as well, but a suffix array is easier to implement.

Errichto's Video

Implementation

Time Complexity: O(N)\mathcal{O}(N)

C++

#include <iostream>
using namespace std;
int main() {
string s;
cin >> s;
int num = 0, n = s.size(), pow = 1;
// initializes array with initializer list
// explained here: https://www.learncpp.com/cpp-tutorial/arrays-part-ii/
int count[2019]{1};

Java

import java.io.*;
import java.util.*;
public class MultipleOf2019 {
public static void main(String[] args) {
Kattio io = new Kattio();
String numberString = io.next();
int num = 0;
int stringLength = numberString.length();
int pow = 1;

Python

MOD = 2019
string = input()
count = [0] * MOD
count[0] = 1
cur_num = 0
power = 1
for c in reversed(string):
# find the remainder of the current number MOD 2019

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!