結果
問題 | No.2758 RDQ |
ユーザー |
|
提出日時 | 2024-05-17 22:10:21 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 163 ms / 2,000 ms |
コード長 | 2,274 bytes |
コンパイル時間 | 3,556 ms |
コンパイル使用メモリ | 126,788 KB |
実行使用メモリ | 48,768 KB |
最終ジャッジ日時 | 2024-12-20 15:45:15 |
合計ジャッジ時間 | 5,355 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 21 |
ソースコード
#include <iostream>#include <vector>#include <algorithm>#include <tuple>#include <cmath>using namespace std;using ll = long long;int main () {int N, Q; cin >> N >> Q;vector<int> A(N);for (int i = 0; i < N; i++) cin >> A[i];// 賢いやり方不明。// ある程度大きなKに対してはMoを適用し、小さなKに対しては空間N√Nで計算しながらやる。vector<int> L(Q), R(Q), K(Q);for (int i = 0; i < Q; i++) {cin >> L[i] >> R[i] >> K[i];L[i]--;// 0-indexedで開区間}vector<int> index(Q), priority(Q);const int width = (int) sqrt((double) Q) + 10;for (int i = 0; i < Q; i++) {index[i] = i;priority[i] = L[i] / width;}sort(index.begin(), index.end(), [&](int x, int y) {if (priority[x] == priority[y]) {if ((priority[x]) % 2 == 0) return R[x] < R[y];return R[y] < R[x];}return priority[x] < priority[y];});const int max_mod = 100000;const int sqrt_N = (int) sqrt((double) N);vector<int> count_all(max_mod + 1);vector<vector<int>> acc(sqrt_N, vector<int>(N + 1, 0));// 前計算for (int i = 1; i < sqrt_N; i++) {for (int j = 0; j < N; j++) {int add = 0;if (A[j] % i == 0) add = 1;acc[i][j + 1] = acc[i][j] + add;}}vector<int> ans(Q);int l = 0, r = 0;// [l, r)for (int i = 0; i < Q; i++) {int idx = index[i];while (l < L[idx]) {count_all[A[l]]--;l++;}while (L[idx] < l) {l--;count_all[A[l]]++;}while (r < R[idx]) {count_all[A[r]]++;r++;}while (R[idx] < r) {r--;count_all[A[r]]--;}if (K[idx] < sqrt_N) {ans[idx] = acc[K[idx]][R[idx]] - acc[K[idx]][L[idx]];}else {int cur = K[idx];while (cur <= max_mod) {ans[idx] += count_all[cur];cur += K[idx];}}}for (auto v : ans) cout << v << "\n";}