关于 洛谷P1494 [国家集训队] 小 Z 的袜子 $OI-WiKi$代码的一些解释 & 莫队 注意事项

关于 洛谷P1494 [国家集训队] 小 Z 的袜子 \(OI-WiKi\)代码的一些解释 & 莫队 注意事项

\(OI-WiKiLink\)

题目Link

  1. 硬性要求 \(add\)\(del\)\(add\)全部是 先修改原数再扔进函数\(del\)全部是 先扔进函数再修改原数

    while (l > q[i].l) add(c[--l]);
    while (r < q[i].r) add(c[++r]);
    while (l < q[i].l) del(c[l++]);
    while (r > q[i].r) del(c[r--]);
    
  2. 输出\(ans\)数组过程必须再判一次若\(ans[i].first\)\(0\)\(ans[i].second\)就为\(1\)的情况。 原因未知

  3. 硬性要求,输入询问时按照\(0\) ~ \(m - 1\)的顺序输入

  4. 硬性要求, 做莫队时\(l、r\)初值:\(l = 1,r = 0\)

AC Code

#include <bits/stdc++.h>
using namespace std;
inline int read() {
    int x = 0; char ch = getchar(); bool sgn = 0;
    while (ch < '0' || ch > '9') sgn |= ch == '-', ch = getchar();
    while (ch >= '0' && ch <= '9') x = x * 10 + (ch & 15), ch = getchar();
    return sgn ? -x : x;
}
const int MN = 5e4 + 10;
int n, m, block, c[MN], cnt[MN];
long long sum;
pair<long long, long long> ans[MN];
struct Query {
    int l, r, id;
    bool operator < (const Query &x) const {
        return l / block != x.l / block ? l < x.l : l / block & 1 ? r < x.r : r > x.r;
    }
} q[MN];
inline void add(int x) {
    sum += cnt[x], cnt[x]++;
}
inline void del(int x) {
    cnt[x]--, sum -= cnt[x];
}
inline long long gcd(long long x, long long y) {
    return !y ? x : gcd(y, x % y);
}
signed main() {
    n = read(), m = read(), block = sqrt(n);
    for (int i = 1; i <= n; ++i) c[i] = read();
    for (int i = 0; i < m; ++i) q[i].l = read(), q[i].r = read(), q[i].id = i;
    sort(q, q + m);
    for (int i = 0, l = 1, r = 0; i < m; ++i) {
        if (q[i].l == q[i].r) {
            ans[q[i].id] = make_pair(0, 1);
            continue;
        }
        while (l > q[i].l) add(c[--l]);
        while (r < q[i].r) add(c[++r]);
        while (l < q[i].l) del(c[l++]);
        while (r > q[i].r) del(c[r--]);
        ans[q[i].id] = make_pair(sum, 1ll * (r - l + 1) * (r - l) / 2ll);
    }
    for (int i = 0; i < m; ++i) {
        if (ans[i].first) {
            long long g = __gcd(ans[i].first, ans[i].second);
            ans[i].first /= g, ans[i].second /= g;
        }
        else ans[i].second = 1;
        cout << ans[i].first << '/' << ans[i].second << '\n';
    }
    return 0;
}
posted @ 2022-06-09 13:48  zjsqwq  阅读(41)  评论(0)    收藏  举报