离线树状数组搞一搞。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PII pair<int, int> #define PLI pair<LL, int> #define ull unsigned long long using namespace std; const int N = 2e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 998244353; const int Mod = 1e9 + 7; int n, m, a[N], ans[N], L[N]; bool vis[N], is[N], ok[N]; vector<PII> v[N]; vector<int> p[N]; map<int,int> mp; struct BIT { int a[N]; void init() { for(int i = 1; i <= n; i++) a[i] = 0; } void modify(int x, int val) { for(int i = x; i <= n; i += i & -i) a[i] += val; } int sum(int x) { int ans = 0; for(int i = x; i; i -= i & -i) ans += a[i]; return ans; } int query(int l, int r) { return sum(r) - sum(l - 1); } } b, c; int main() { for(int i = 2; i < N; i++) { if(is[i]) continue; for(int j = i; j < N; j += i) { is[j] = true; p[j].push_back(i); } } while(scanf("%d%d", &n, &m)!= EOF && (n || m)) { b.init(); mp.clear(); c.init(); for(int i = 1; i <= n; i++) { v[i].clear(); vis[i] = ok[i] = true; scanf("%d", &a[i]); b.modify(i, 1); L[i] = inf; } for(int i = 1; i <= m; i++) { int l, r; scanf("%d%d", &l, &r); v[l].push_back(mk(r, i)); } for(int i = n; i >= 1; i--) { for(int t : p[a[i]]) { if(mp.find(t) != mp.end()) { int pos = mp[t]; L[i] = min(L[i], pos); if(vis[pos]) { vis[pos] = false; b.modify(pos, -1); } else if(ok[pos] && L[pos] != inf){ ok[pos] = false; c.modify(pos, -1); c.modify(L[pos], 1); } } mp[t] = i; } if(L[i] != inf) { vis[i] = false; b.modify(i, -1); c.modify(i, 1); c.modify(L[i], -1); } for(PII t : v[i]) { ans[t.se] = b.query(i, t.fi) + c.sum(t.fi); } } for(int i = 1; i <= m; i++) printf("%d ", ans[i]); } return 0; } /**/