QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#535465#9228. ICPC Inferenceucup-team004WA 186ms54352kbC++207.0kb2024-08-28 04:10:352024-08-28 04:10:35

Judging History

你现在查看的是最新测评结果

  • [2024-08-28 04:10:35]
  • 评测
  • 测评结果:WA
  • 用时:186ms
  • 内存:54352kb
  • [2024-08-28 04:10:35]
  • 提交

answer

#include <bits/stdc++.h>

using i64 = long long;

constexpr int K = 20;

constexpr i64 M = 1E16;
template <typename T>
struct Fenwick {
    int n;
    std::vector<T> a;
    
    Fenwick(int n_ = 0) {
        init(n_);
    }
    
    void init(int n_) {
        n = n_;
        a.assign(n, T{});
    }
    
    void add(int x, const T &v) {
        for (int i = x + 1; i <= n; i += i & -i) {
            a[i - 1] = a[i - 1] + v;
        }
    }
    
    T sum(int x) {
        T ans{};
        for (int i = x; i > 0; i -= i & -i) {
            ans = ans + a[i - 1];
        }
        return ans;
    }
    
    T rangeSum(int l, int r) {
        return sum(r) - sum(l);
    }
    
    int select(const T &k) {
        int x = 0;
        T cur{};
        for (int i = 1 << std::__lg(n); i; i /= 2) {
            if (x + i <= n && cur + a[x + i - 1] <= k) {
                x += i;
                cur = cur + a[x - 1];
            }
        }
        return x;
    }
};

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    int N, D, L;
    std::cin >> N >> D >> L;
    
    std::vector<std::vector<int>> vec(D);
    for (int i = 0; i < N; i++) {
        int d, t;
        std::cin >> d >> t;
        d--;
        vec[d].push_back(t);
    }
    
    std::vector<i64> bronze(D), gold(D);
    
    std::vector<int> teams;
    for (int i = 0; i < D; i++) {
        if (vec[i].empty()) {
            continue;
        }
        teams.push_back(i);
    }
    
    for (auto i : teams) {
        bronze[i] = M - vec[i].back() - (vec[i].size() - 1) * K;
        for (int j = 0; j < std::min<int>(vec[i].size(), 13); j++) {
            gold[i] += M - vec[i][j];
        }
    }
    
    i64 ans = 0;
    
    std::vector<i64> b, g;
    for (auto i : teams) {
        b.push_back(bronze[i]);
        g.push_back(gold[i]);
    }
    std::sort(b.begin(), b.end());
    std::sort(g.begin(), g.end());
    
    std::vector<i64> pre(g.size() + 1);
    i64 tot = 0;
    for (int i = 0, j = 0; i < g.size(); i++) {
        while (j < b.size() && b[j] <= g[i]) {
            j++;
        }
        pre[i + 1] = pre[i] + j;
        tot += j - 1;
    }
    
    std::vector<i64> bs[K];
    std::vector<std::array<i64, 3>> val[K];
    std::vector<i64> f[K][K];
    
    for (int i = 0; i < b.size(); i++) {
        for (int x = 0; x < K; x++) {
            auto [l, r] = std::equal_range(g.begin(), g.end(), b[i] + x);
            if (l < r) {
                bs[b[i] % K].push_back(b[i]);
                val[b[i] % K].push_back({b[i], b[i] + x, l - r});
            }
        }
    }
    for (auto i : teams) {
        if (gold[i] - bronze[i] < K) {
            bs[bronze[i] % K].push_back(bronze[i]);
            val[bronze[i] % K].push_back({bronze[i], gold[i], 1});
        }
    }
    
    for (int rem = 0; rem < K; rem++) {
        std::sort(bs[rem].begin(), bs[rem].end());
        std::sort(val[rem].begin(), val[rem].end());
        for (int i = 0; i < K; i++) {
            f[rem][i].resize(bs[rem].size() + 1);
            for (int j = 0; j < val[rem].size(); j++) {
                auto [l, r, v] = val[rem][j];
                f[rem][i][j + 1] += f[rem][i][j] + (r - l <= i) * v;
            }
        }
    }
    
    auto query = [&](i64 l, i64 r, int rem, int i) -> i64 {
        assert(0 <= i && i < K);
        if (l == r) {
            return 0;
        }
        int lo = std::lower_bound(bs[rem].begin(), bs[rem].end(), l) - bs[rem].begin();
        int hi = std::lower_bound(bs[rem].begin(), bs[rem].end(), r) - bs[rem].begin();
        return f[rem][i][hi] - f[rem][i][lo];
    };
    
    std::vector<std::array<i64, 2>> ask;
    // std::cerr << tot << "\n";
    for (auto i : teams) {
        // std::cerr << "- " << i + 1 << " " << bronze[i] << " " << gold[i] << "\n";
        std::vector<std::array<i64, 3>> s;
        auto add = [&](i64 r, int k) {
            i64 l = r - k * K;
            s.push_back({l - l % K, l % K, 1});
            s.push_back({r - r % K + K, l % K, -1});
        };
        for (int j = 0; j < vec[i].size(); j++) {
            add(M - vec[i][j], j);
        }
        if (vec[i].size() >= 2) {
            add(2 * M - vec[i].back() - vec[i].end()[-2] - (vec[i].size() - 2) * K, 0);
        }
        std::sort(s.begin(), s.end());
        ans += tot;
        
        auto check = [&](i64 l, i64 r) {
            if (r - l < 1) {
                return;
            }
            l++;
            int lo = std::lower_bound(g.begin(), g.end(), l) - g.begin();
            int hi = std::lower_bound(g.begin(), g.end(), r) - g.begin();
            ans -= pre[hi] - pre[lo];
            ans += 1LL * (hi - lo) * (std::lower_bound(b.begin(), b.end(), l) - b.begin());
            ask.push_back({l, r});
        };
        
        i64 lst = 0;
        i64 l = 0;
        
        std::array<int, K> cnt{};
        
        for (auto [r, rem, tp] : s) {
            if (r > l) {
                if (std::count(cnt.begin(), cnt.end(), 0) < K) {
                    int t = -1;
                    for (int x = 0; x < K; x++) {
                        if (cnt[x] > 0) {
                            if (t != -1) {
                                for (int y = t + 1; y + 1 < x; y++) {
                                    ans += query(l, r, y, x - 1 - y);
                                }
                            }
                            t = x;
                        }
                    }
                    for (int x = 0; x < K; x++) {
                        if (cnt[x] > 0) {
                            check(lst, l + x);
                            for (int y = t + 1; y + 1 < x + K; y++) {
                                ans += query(l, r - K, y % K, x + K - 1 - y);
                            }
                            break;
                        }
                    }
                    for (int x = 0; x < K; x++) {
                        if (cnt[x] > 0) {
                            lst = r - K + x;
                        }
                    }
                }
                l = r;
            }
            cnt[rem] += tp;
        }
        
        check(lst, 1E18);
        
        ans -= g.end() - std::lower_bound(g.begin(), g.end(), bronze[i]);
        ans -= std::upper_bound(b.begin(), b.end(), gold[i]) - b.begin();
        ans += 2;
    }
    
    Fenwick<int> fen(b.size());
    std::sort(ask.begin(), ask.end(), std::greater());
    auto ord = teams;
    std::sort(ord.begin(), ord.end(),
        [&](int i, int j) {
            return bronze[i] < bronze[j];
        });
    for (int i = ord.size(); auto [l, r] : ask) {
        while (i > 0 && bronze[ord[i - 1]] >= l) {
            i--;
            int j = std::lower_bound(g.begin(), g.end(), gold[ord[i]]) - g.begin();
            fen.add(j, 1);
        }
        ans += fen.sum(std::lower_bound(g.begin(), g.end(), r) - g.begin());
    }
    
    std::cout << ans << "\n";
    
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3468kb

input:

4 3 300
1 10
2 25
2 30
3 50

output:

3

result:

ok 1 number(s): "3"

Test #2:

score: 0
Accepted
time: 0ms
memory: 3588kb

input:

4 6 200000
6 1
6 1
1 2
2 2

output:

4

result:

ok 1 number(s): "4"

Test #3:

score: -100
Wrong Answer
time: 186ms
memory: 54352kb

input:

191580 64997 56
24878 1
35060 1
24245 1
64330 1
9650 1
15423 1
34953 1
21456 1
36718 1
21395 1
17613 1
16995 1
45257 1
31277 1
20026 1
1870 1
25581 1
9997 1
54701 1
30752 1
32269 1
705 1
64186 1
58881 1
24614 1
55311 1
18259 1
58886 1
23296 1
17628 1
3411 1
37469 1
47951 1
12188 1
60720 1
54168 1
45...

output:

274534697928900

result:

wrong answer 1st numbers differ - expected: '274533940012863', found: '274534697928900'