D题的莫队写法
比赛时没认真看范围,磨了半天磨了个莫队
#include <bits/stdc++.h>
#define fu(a, b, c) for (int a = b; a <= c; a++)
#define fd(a, b, c) for (int a = b; a >= c; a--)
#define mx(a, b) a = max(a, b)
#define mn(a, b) a = min(a, b)
using namespace std;
using ll = long long;
const int N = 1e5 + 1, B = sqrt(N);
int n, m, l, r, a[N];
ll cnt, ans[N];
unordered_map<int, int> mp;
int cal(int x) {
int res = 1;
for (int i = 2; i * i <= x; ++i) {
int t = 0;
while (x % i == 0)
x /= i, ++t;
res *= t + 1;
}
return x > 1 ? res << 1 : res;
}
struct q {
int l, r, b, id;
bool operator<(q a) {
return b ^ a.b ? l < a.l : b & 1 ? r > a.r
: r < a.r;
}
} q[N];
inline void add(int x) { cnt += mp[a[x]], ++mp[a[x]]; }
inline void del(int x) { cnt -= mp[a[x]] - 1, --mp[a[x]]; }
int main() {
ios::sync_with_stdio(0), cin.tie(0);
cin >> n >> m;
fu(i, 1, n) cin >> a[i], a[i] = cal(a[i]);
fu(i, 1, m) cin >> l >> r, q[i] = {l, r, l / B, i};
sort(q + 1, q + m + 1);
l = 1, r = 0;
fu(i, 1, m) {
// cout << q[i].l << ' ' << q[i].r << ' ';
while (l > q[i].l)
add(--l);
while (r < q[i].r)
add(++r);
while (l < q[i].l)
del(l++);
while (r > q[i].r)
del(r--);
// for (auto [k, v] : mp)
// cout << k << ' ' << v << '\t';
ans[q[i].id] = cnt;
// cout << cnt << '\n';
}
fu(i, 1, m) cout << ans[i] << '\n';
}
