QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#156628 | #7108. Couleur | ucup-team1134# | AC ✓ | 1644ms | 139920kb | C++17 | 6.3kb | 2023-09-02 13:55:13 | 2023-09-02 14:51:44 |
Judging History
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