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';
}

全部评论

相关推荐

牛客吹哨人:哨哥晚点统一更新到黑名单:能救一个是一个!26届毁意向毁约裁员黑名单https://www.nowcoder.com/discuss/1525833
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务