數組 a[1..n] (n≤1e5, a_i≤1e6),q≤1e5 查詢:區間 [L,R] 中有多少個數是質數 P (P≤1e6) 的倍數。
1e6 內所有質數及最小質因子 lp[x]。a[i] 分解質因子(去重),對每個質因子 p,將位置 i 加入 pos[p] 列表。(L,R,P):在 pos[P] 中二分查找 [L,R] 內位置個數。
const int MAXV = 1e6;
int lp[MAXV+1], primes[MAXV], pcnt;
void sieve() {
for (int i=2;i<=MAXV;++i) {
if (!lp[i]) lp[i]=i, primes[pcnt++]=i;
for (int j=0;j pos[MAXV+1];
void addNumber(int idx, int x) {
while (x > 1) {
int p = lp[x];
pos[p].push_back(idx);
while (x % p == 0) x /= p;
}
}
int query(int L, int R, int P) {
auto& v = pos[P];
if (v.empty()) return 0;
auto itL = lower_bound(v.begin(), v.end(), L);
auto itR = upper_bound(v.begin(), v.end(), R);
return itR - itL;
}
O(MAXV)。n 個數:每個數質因子數 ≤ 7,總 O(n log MAXV)。O(log |pos[P]|),總 O(q log n)。∑ |pos[p]| ≤ n * 7 ≈ 7e5。vector 存儲位置,天然有序(按 idx 遞增插入)。scanf/printf 或關閉同步)。