結果

問題 No.2620 Sieve of Coins
ユーザー SSRSSSRS
提出日時 2024-01-26 23:25:36
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
MLE  
実行時間 -
コード長 4,816 bytes
コンパイル時間 2,986 ms
コンパイル使用メモリ 232,468 KB
実行使用メモリ 814,032 KB
最終ジャッジ日時 2024-01-26 23:25:42
合計ジャッジ時間 4,986 ms
ジャッジサーバーID
(参考情報)
judge13 / judge14
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,676 KB
testcase_01 AC 2 ms
6,676 KB
testcase_02 AC 3 ms
6,676 KB
testcase_03 MLE -
testcase_04 -- -
testcase_05 -- -
testcase_06 -- -
testcase_07 -- -
testcase_08 -- -
testcase_09 -- -
testcase_10 -- -
testcase_11 -- -
testcase_12 -- -
testcase_13 -- -
testcase_14 -- -
testcase_15 -- -
testcase_16 -- -
testcase_17 -- -
testcase_18 -- -
testcase_19 -- -
testcase_20 -- -
testcase_21 -- -
testcase_22 -- -
testcase_23 -- -
testcase_24 -- -
testcase_25 -- -
testcase_26 -- -
testcase_27 -- -
testcase_28 -- -
testcase_29 -- -
testcase_30 -- -
testcase_31 -- -
testcase_32 -- -
testcase_33 -- -
testcase_34 -- -
testcase_35 -- -
testcase_36 -- -
testcase_37 -- -
testcase_38 -- -
testcase_39 -- -
testcase_40 -- -
testcase_41 -- -
testcase_42 -- -
testcase_43 -- -
testcase_44 -- -
testcase_45 -- -
testcase_46 -- -
testcase_47 -- -
testcase_48 -- -
testcase_49 -- -
testcase_50 -- -
testcase_51 -- -
testcase_52 -- -
testcase_53 -- -
testcase_54 -- -
testcase_55 -- -
testcase_56 -- -
testcase_57 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;
#include <bits/stdc++.h>
using namespace std;
const long long MOD = 998244353;
long long modpow(long long a, long long b){
  long long ans = 1;
  while (b > 0){
    if (b % 2 == 1){
      ans *= a;
      ans %= MOD;
    }
    a *= a;
    a %= MOD;
    b /= 2;
  }
  return ans;
}
long long modinv(long long a){
  return modpow(a, MOD - 2);
}
vector<pair<int, pair<int, int>>> quotient_ranges(int N){
	vector<pair<int, pair<int, int>>> ans;
	for (int i = 1; i * i <= N; i++){
		ans.push_back(make_pair(N / i, make_pair(i, i)));
	}
	for (int i = N / ((int) sqrt(N) + 1); i >= 1; i--){
		ans.push_back(make_pair(i, make_pair(N / (i + 1) + 1, N / i)));
	}
	return ans;
}
long long sqrt_floor(long long N){
  long long tv = 0, fv = 1100000000;
  while (fv - tv > 1){
    long long mid = (tv + fv) / 2;
    if (mid * mid <= N){
      tv = mid;
    } else {
      fv = mid;
    }
  }
  return tv;
}
bool is_square_number(long long N){
  long long x = sqrt_floor(N);
  return x * x == N;
}
long long cbrt_floor(long long N){
  long long tv = 0, fv = 1100000;
  while (fv - tv > 1){
    long long mid = (tv + fv) / 2;
    if (mid * mid * mid <= N){
      tv = mid;
    } else {
      fv = mid;
    }
  }
  return tv;
}
long long cbrt_ceil(long long N){
  return cbrt_floor(N - 1) + 1;
}
pair<vector<long long>, vector<long long>> dirichlet_sum_division(long long N, int K, int L, vector<long long> a, vector<long long> c, vector<long long> A, vector<long long> C){
  vector<long long> b = c;
  long long INV_a1 = modinv(a[1]);
  for (int i = 1; i <= K; i++){
    b[i] *= INV_a1;
    b[i] %= MOD;
    for (int j = i * 2; j <= K; j += i){
      b[j] += MOD - a[j / i] * b[i] % MOD;
      b[j] %= MOD;
    }
  }
  vector<long long> asum(K + 1), bsum(K + 1);
  asum[0] = 0;
  bsum[0] = 0;
  for (int i = 1; i <= K; i++){
    asum[i] = (asum[i - 1] + a[i]) % MOD;
    bsum[i] = (bsum[i - 1] + b[i]) % MOD;
  }
  vector<long long> B(L + 1, 0);
  for (int i = L; i >= 1; i--){
    B[i] = C[i];
    long long M = sqrt_floor(N / i);
    for (int j = 2; j <= M; j++){
      if (N / i / j <= K){
        B[i] += MOD - a[j] * bsum[N / i / j] % MOD;
        B[i] %= MOD;
      } else {
        B[i] += MOD - a[j] * B[i * j] % MOD;
        B[i] %= MOD;
      }
    }
    long long AM;
    if (M <= K){
      AM = asum[M];
    } else {
      AM = A[N / M];
    }
    for (int j = 1; j <= M; j++){
      if (N / i / j <= K){
        B[i] += MOD - b[j] * asum[N / i / j] % MOD;
      } else {
        B[i] += MOD - b[j] * A[i * j] % MOD;
      }
      B[i] += b[j] * AM;
      B[i] %= MOD;
    }
    B[i] *= INV_a1;
    B[i] %= MOD;
  }
  return make_pair(b, B);
}
long long solve(long long N){
  if (N == 0){
    return 0;
  }
  vector<long long> small, large;
  int L = cbrt_ceil(N);
  int K = (N + L - 1) / L;
  vector<long long> a(K + 1, 0), c(K + 1, 0);
  vector<long long> A(L + 1, 0), C(L + 1, 0);
  for (int i = 1; i <= K; i++){
    c[i] = 1;
  }
  for (int i : {1, 2, 3, 6}){
    for (int j = 1; j * j * i <= K; j++){
      a[j * j * i]++;
    }
  }
  for (int i = 1; i <= L; i++){
    for (int j : {1, 2, 3, 6}){
      A[i] += sqrt_floor(N / i / j);
    }
    C[i] = N / i;
  }
  vector<long long> b, B;
  tie(b, B) = dirichlet_sum_division(N, K, L, a, c, A, C);
  return B[1];
};
int main(){
  long long L;
  int N;
  cin >> L >> N;
  vector<long long> A(N);
  for (int i = 0; i < N; i++){
    cin >> A[i];
  }
  vector<long long> P2 = {1};
  while (P2.back() * 2 <= L){
    long long x = P2.back() * 2;
    P2.push_back(x);
  }
  vector<long long> P3 = {1};
  while (P3.back() * 3 <= L){
    long long x = P3.back() * 3;
    P3.push_back(x);
  }
  int C2 = P2.size();
  int C3 = P3.size();
  vector<vector<long long>> V(C2, vector<long long>(C3));
  for (int i = 0; i < C2; i++){
    for (int j = 0; j < C3; j++){
      if (L / P2[i] < P3[j]){
        V[i][j] = L + 1;
      } else {
        V[i][j] = P2[i] * P3[j];
      }
    }
  }
  map<long long, pair<int, int>> mp;
  for (int i = 0; i < C2; i++){
    for (int j = 0; j < C3; j++){
      if (V[i][j] <= L){
        mp[V[i][j]] = make_pair(i, j);
      }
    }
  }
  vector<vector<bool>> head(C2, vector<bool>(C3, false));
  for (int i = 0; i < N; i++){
    pair<int, int> P = mp[A[i]];
    head[P.first][P.second] = true;
  }
  for (int i = 0; i < C2; i++){
    for (int j = 0; j < C3; j++){
      if (head[i][j]){
        for (int k = i; k < C2; k++){
          for (int l = j; l < C3; l++){
            if (!(k == i && l == j)){
              head[k][l] = !head[k][l];
            }
          }
        }
      }
    }
  }
  long long ans = 0;
  for (int i = 0; i < C2; i++){
    for (int j = 0; j < C3; j++){
      if (head[i][j] && V[i][j] <= L){
        ans += solve(L / V[i][j]);
      }
    }
  }
  cout << ans << endl;
}
0