Codeforces Round #506 (Div. 3) D. Concatenated Multiples
問題概要
正整数,と,個の正整数が与えられる.とを連結させた数のうち,で割り切れるペアの個数を答えよ.ただし.連結させた数の例としては,となら.とならとする.
解法パートで,とを連結させた数をという風に書く.
解法
を,mod でにしたいと考える.にを足したら,mod でになる.正整数は高々個あるので,一つのに対して条件を満たすが何個あるかを高速に求めたい.
ここで,をの桁数とする.,と言った感じ.こうすると,とを固定し,という連結させた数がと表せる.例えば,,とすると,であってと書ける.
上のように書いて何がうれしいかと言うと,和の前と後でバラバラにmodを取れることである.つまり,というように計算できる.上の例では,とするととなる.
最初にしたかったことを思い出す.一つのに対して条件を満たすが何個あるかを高速に求めたい.前処理として,を取り得るに対してすべて計算し,何個あるかカウントしておくと最初にしたかったことができる.
が取り得る値の範囲を考える.こういうときは制約を見返すとよくて,である.したがって,は高々桁にしかならないので,である.
このようにして各に対して,をの範囲ですべて計算してから個数カウントする前処理をした後で,各ごとにの個数を足し合わせたら,答えが求まる.
TLが2secだとギリギリだったり,とが同じになるとき(これをカウントしてしまうととのペアを数えることになる)に注意しながら実装する.
実装
コード
// #define _GLIBCXX_DEBUG
// #pragma GCC optimize("Ofast")
#pragma GCC diagnostic ignored "-Wsign-compare"
#include <bits/stdc++.h>
// #include <atcoder/all>
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define reps(i, s, n) for (int i = s; i < (int)(n); ++i)
using namespace std;
using ll = long long;
template <class T> using V = vector<T>;
template <class T> using VV = V<V<T>>;
template <class T> inline bool chmax(T& a, T b) {
if (a < b) {
a = b;
return true;
}
return false;
}
template <class T> inline bool chmin(T& a, T b) {
if (a > b) {
a = b;
return true;
}
return false;
}
constexpr int INF = 1e9 + 7;
constexpr ll LINF = 1LL << 60;
int calc_digit(ll a) {
int ret = 0;
while (a > 0) {
ret++;
a /= 10;
}
return ret;
}
void solve() {
ll n, k;
cin >> n >> k;
V<ll> A(n);
rep(i, n) cin >> A[i];
VV<ll> val(11, V<ll>(n));
rep(i, n) {
ll v = A[i];
rep(d, 11) {
val[d][i] = v;
v *= 10;
v %= k;
}
}
map<ll, ll> cnt[11];
rep(d, 11) {
rep(i, n) { cnt[d][val[d][i]]++; }
}
ll ans = 0;
rep(i, n) {
int d = calc_digit(A[i]);
ll need = (k - A[i] % k) % k; // A[i] % k = 0のときがあるので,外側でも % kする
ans += cnt[d][need];
if (need == val[d][i]) ans--;
}
cout << ans << "\n";
}
int main() {
cin.tie(nullptr);
// ios_base::sync_with_stdio(false);
// cout << fixed << setprecision(15);
solve();
}
サンプル
# input 6 23 45 1 10 12 11 7 # output 1
以下三枚,サンプルを考えるときのメモ(手書きで読みにくかったらすみません).
だけがmod でになる.
mapのアクセスのしかたを変えると,TLEして苦戦した.メモリの局所性を感じる.あとmapを要素とした配列を初めて使った.Pythonならdictを要素としたリスト.言語をあっちこっち使うと混乱しそうになる.