QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#156628#7108. Couleurucup-team1134#AC ✓1644ms139920kbC++176.3kb2023-09-02 13:55:132023-09-02 14:51:44

Judging History

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

  • [2023-09-02 14:51:44]
  • 评测
  • 测评结果:AC
  • 用时:1644ms
  • 内存:139920kb
  • [2023-09-02 13:55:13]
  • 提交

answer

// https://judge.yosupo.jp/submission/28420

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=998244353,MAX=300005,INF=1<<30;

#include <cassert>
#include <cmath>
#include <algorithm>
#include <utility>
#include <vector>

// CUT begin
// Static Range Inversion Query (Online)
// Complexity: O((N + Q)sqrt(N)) time, O(Nsqrt(N)) space (~128MB for N=1e5)
// Reference: <https://stackoverflow.com/questions/21763392/counting-inversions-in-ranges>
template <typename T>
struct StaticRangeInversion {
    const int N;
    const int bs;    // bucket size
    const int nb_bc; // # of buckets
    std::vector<int> vals;
    std::vector<std::pair<int, int>> vals_sorted;
    std::vector<std::vector<int>> presuf;
    std::vector<int> sufG, preH;
    std::vector<std::vector<long long>> R;
    
    StaticRangeInversion(const std::vector<T> &sequence) : N(sequence.size()), bs(ceil(sqrt(std::max(N, 1)))), nb_bc((N + bs - 1) / bs) {
        std::vector<T> dict = sequence;
        std::sort(dict.begin(), dict.end()), dict.erase(std::unique(dict.begin(), dict.end()), dict.end());
        const int D = dict.size();
        vals.reserve(N), vals_sorted.reserve(N);
        for (auto x : sequence) {
            vals.emplace_back(std::lower_bound(dict.begin(), dict.end(), x) - dict.begin());
            vals_sorted.emplace_back(vals.back(), int(vals.size()) - 1);
        }
        
        presuf.assign(nb_bc, std::vector<int>(N));
        sufG.resize(N), preH.resize(N);
        
        for (int ibc = 0; ibc < nb_bc; ibc++) {
            const int L = ibc * bs, R = std::min(L + bs, N);
            std::sort(vals_sorted.begin() + L, vals_sorted.begin() + R);
            std::vector<int> cnt(D + 1);
            for (int i = L; i < R; i++) {
                cnt[vals[i] + 1]++;
            }
            for (int i = 0; i < D; i++) {
                cnt[i + 1] += cnt[i];
            }
            for (int b = 0; b < ibc; b++) {
                for (int i = (b + 1) * bs - 1; i >= b * bs; i--) {
                    presuf[ibc][i] = presuf[ibc][i + 1] + cnt[vals[i]];
                }
            }
            for (int b = ibc + 1; b < bs; b++) {
                for (int i = b * bs; i < std::min((b + 1) * bs, N); i++) {
                    presuf[ibc][i] = (i == b * bs ? 0 : presuf[ibc][i - 1]) + cnt.back() - cnt[vals[i] + 1];
                }
            }
            for (int i = L + 1; i < R; i++) {
                preH[i] = preH[i - 1] + std::count_if(vals.begin() + L, vals.begin() + i, [&](int x) { return x > vals[i]; });
            }
            for (int i = R - 2; i >= L; i--) {
                sufG[i] = sufG[i + 1] + std::count_if(vals.begin() + i + 1, vals.begin() + R, [&](int x) { return x < vals[i]; });
            }
        }
        R.resize(nb_bc, std::vector<long long>(nb_bc));
        
        for (int i = 0; i < nb_bc; i++) {
            R[i][i] = sufG[i * bs];
        }
        for (int w = 1; w < nb_bc; w++) {
            for (int i = 0; i < nb_bc - w; i++) {
                R[i][i + w] = R[i][i + w - 1] + R[i + 1][i + w] - R[i + 1][i + w - 1] + presuf[i + w][i * bs];
            }
        }
        // for (int ibc = 0; ibc < nb_bc; ibc++) {
        //     const int L = ibc * bs;
        //     R[ibc][ibc] = sufG[L];
        //     for (int jbc = ibc + 1; jbc < nb_bc; jbc++) {
        //         R[ibc][jbc] = R[ibc][jbc - 1] + sufG[jbc * bs];
        //         for (int kbc = ibc; kbc < jbc; kbc++) {
        //             R[ibc][jbc] += presuf[jbc][kbc * bs];
        //         }
        //     }
        // }
    }
    long long get(int l, int r) const {
        assert(l >= 0 and l <= N and r >= 0 and r <= N and l <= r);
        long long ret = 0;
        if (r - l <= bs) {
            for (int i = l + 1; i < r; i++) {
                ret += std::count_if(vals.begin() + l, vals.begin() + i, [&](int x) { return x > vals[i]; });
            }
            return ret;
        }
        const int lb = (l + bs - 1) / bs, rb = (r == N ? nb_bc : r / bs) - 1;
        if (lb <= rb) {
            ret += R[lb][rb];
        }
        if (bs * lb > l) {
            ret += sufG[l];
            for (int b = lb; b <= rb; b++) {
                ret += presuf[b][l];
            }
        }
        if (bs * (rb + 1) < r) {
            ret += preH[r - 1];
            for (int b = lb; b <= rb; b++) {
                ret += presuf[b][r - 1];
            }
        }
        
        int less_cnt = 0, j = (rb + 1) * bs;
        for (int p = std::max(0, (lb - 1) * bs), q = lb * bs; p < q; p++) {
            if (vals_sorted[p].second >= l) {
                while (j < std::min(N, (rb + 2) * bs) and (vals_sorted[j].second >= r or vals_sorted[j].first < vals_sorted[p].first)) {
                    if (vals_sorted[j].second < r) {
                        less_cnt++;
                    }
                    j++;
                }
                ret += less_cnt;
            }
        }
        return ret;
    }
};

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    int QQ;cin>>QQ;
    while(QQ--){
        int N;cin>>N;
        vector<int> A(N);
        for(int i=0;i<N;i++) cin>>A[i];
        StaticRangeInversion riq(A);
        ll la=0;
        multiset<ll> SE;
        set<int> dead;
        dead.insert(-1);
        dead.insert(N);
        
        SE.insert(riq.get(0,N));
        cout<<(*SE.rbegin());
        la=(*SE.rbegin());
        
        for(int q=0;q<N;q++){
            ll x;cin>>x;
            x=x^la;x--;
            auto l2=dead.lower_bound(x),r2=l2;
            l2--;
            ll L=(*l2)+1,R=(*r2);
            SE.erase(SE.find(riq.get(L,R)));
            SE.insert(riq.get(L,x));
            SE.insert(riq.get(x+1,R));
            dead.insert(x);
            if(q==N-1) break;
            
            cout<<" "<<(*SE.rbegin());
            la=(*SE.rbegin());
        }
        cout<<"\n";
    }
}

这程序好像有点Bug,我给组数据试试?

详细

Test #1:

score: 100
Accepted
time: 2ms
memory: 3680kb

input:

3
5
4 3 1 1 1
5 4 5 3 1
10
9 7 1 4 7 8 5 7 4 8
21 8 15 5 9 2 4 5 10 6
15
4 8 8 1 12 1 10 14 7 14 2 9 13 10 3
37 19 23 15 7 2 10 15 2 13 4 5 8 7 10

output:

7 0 0 0 0
20 11 7 2 0 0 0 0 0 0
42 31 21 14 14 4 1 1 1 0 0 0 0 0 0

result:

ok 3 lines

Test #2:

score: 0
Accepted
time: 1644ms
memory: 139920kb

input:

11116
10
10 5 10 3 6 4 8 5 9 8
31 27 24 11 12 3 0 2 3 1
10
8 2 7 2 8 10 1 10 9 10
6 5 2 13 2 1 0 1 3 1
10
7 10 7 6 1 3 10 6 7 9
21 18 10 1 6 5 4 8 9 10
10
2 10 4 8 8 5 7 2 6 7
20 10 9 1 15 0 4 2 9 7
10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
10
1 2 3 4 5 6 7 8 9 10
6 3 5 2 7 10 9 1 4 8
10
1 10 1 3...

output:

21 18 16 12 10 6 4 1 1 0
12 12 10 10 4 4 4 2 1 0
20 16 9 5 3 3 3 0 0 0
22 14 8 8 5 5 2 1 1 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
19 12 7 4 4 2 2 1 0 0
20 18 8 3 1 1 0 0 0 0
45 21 21 10 3 3 3 0 0 0
17 11 8 2 1 1 1 0 0 0
13 4 1 0 0 0 0 0 0 0
29 27 22 15 9 7 4 3 1 0
26 16 9 2 1 1 1 1 1 0
0 0 0 0 0 ...

result:

ok 11116 lines

Extra Test:

score: 0
Extra Test Passed