QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#157224 | #7108. Couleur | ucup-team1631# | AC ✓ | 3125ms | 20460kb | C++17 | 6.4kb | 2023-09-02 15:06:01 | 2023-09-02 15:06:01 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T>
bool chmax(T& a, const T& b) {
return a < b ? (a = b, 1) : 0;
}
template <typename T>
bool chmin(T& a, const T& b) {
return a > b ? (a = b, 1) : 0;
}
class BitVector {
public:
BitVector() = default;
explicit BitVector(const std::vector<bool>& v) {
const int n = v.size() / sz + 1;
data.resize(n);
sum.resize(n + 1);
for (int i = 0; i < (int)v.size(); ++i)
data[i / sz] |= v[i] << (i % sz);
for (int i = 0; i < n; ++i)
sum[i + 1] = sum[i] + __builtin_popcount(data[i]);
}
bool operator[](int k) const { return data[k / sz] >> (k % sz) & 1; }
int rank(int k, bool b) const {
int mask = (1U << (k % sz)) - 1;
int r = sum[k / sz] + __builtin_popcount(data[k / sz] & mask);
return b ? r : k - r;
}
int select(int k, bool b) const {
int lb = 0, ub = data.size();
while (ub - lb > 1) {
int m = (lb + ub) / 2;
if (rank(m, b) <= k)
lb = m;
else
ub = m;
}
return lb;
}
private:
static constexpr int sz = 32;
std::vector<uint32_t> data;
std::vector<int> sum;
};
template <typename T>
class WaveletMatrix {
public:
WaveletMatrix() = default;
explicit WaveletMatrix(std::vector<T> v) {
int n = v.size();
T m = *std::max_element(v.begin(), v.end());
int d = 0;
while ((1 << d) <= m) ++d;
mat.resize(d);
cnt0.resize(d);
for (d -= 1; d >= 0; --d) {
std::vector<bool> bit(n);
for (int i = 0; i < n; ++i) bit[i] = v[i] >> d & 1;
mat[d] = BitVector(bit);
std::vector<int> cnt(2);
for (int i = 0; i < n; ++i)
if (!bit[i]) cnt[0]++;
cnt0[d] = cnt[0];
cnt[1] = n;
std::vector<T> nv(n);
for (int i = n - 1; i >= 0; --i) nv[--cnt[bit[i]]] = v[i];
v.swap(nv);
}
for (int i = 0; i < n; ++i)
if (!start.count(v[i])) start[v[i]] = i;
}
T operator[](int k) const {
T ret = 0;
for (int d = mat.size() - 1; d >= 0; --d) {
bool b = mat[d][k];
ret |= T(b) << d;
k = cnt0[d] * b + mat[d].rank(k, b);
}
return ret;
}
int rank(int k, T x) const {
for (int d = mat.size() - 1; d >= 0; --d) {
bool b = x >> d & 1;
k = cnt0[d] * b + mat[d].rank(k, b);
}
if (start.count(x)) return k - start.at(x);
return k;
}
int rank_less(int k, T x) const {
int ret = 0;
int l = 0;
for (int d = mat.size() - 1; d >= 0; --d) {
bool b = x >> d & 1;
if (b) ret += mat[d].rank(k, 0) - mat[d].rank(l, 0);
l = cnt0[d] * b + mat[d].rank(l, b);
k = cnt0[d] * b + mat[d].rank(k, b);
}
return ret;
}
int rank_less(int l, int r, T x) const {
return rank_less(r, x) - rank_less(l, x);
}
int rank_greater(int k, T x) const {
return k - (rank(k, x) + rank_less(k, x));
}
int rank_greater(int l, int r, T x) const {
return rank_greater(r, x) - rank_greater(l, x);
}
int select(int k, T x) const {
k += start.at(x);
for (int d = 0; d < (int)mat.size(); ++d) {
bool b = x >> d & 1;
k = mat[d].select(k - cnt0[d] * b, b);
}
return k;
}
T quantile(int l, int r, int k) const {
T ret = 0;
for (int d = (int)mat.size() - 1; d >= 0; --d) {
int cnt = mat[d].rank(r, 0) - mat[d].rank(l, 0);
bool b = k < cnt ? 0 : 1;
l = cnt0[d] * b + mat[d].rank(l, b);
r = cnt0[d] * b + mat[d].rank(r, b);
if (b) {
ret |= T(1) << d;
k -= cnt;
}
}
return ret;
}
private:
std::vector<BitVector> mat;
std::vector<int> cnt0;
std::unordered_map<T, int> start;
};
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout << fixed << setprecision(15);
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
vector<int> a(n);
for (auto& x : a) cin >> x;
WaveletMatrix<int> wm(a);
vector<ll> ans;
// first ans
ll inv = 0;
rep(i, 0, n) {
inv += wm.rank_less(n, a[i]) - wm.rank_less(i + 1, a[i]);
}
ans.push_back(inv);
set<pair<int, ll>> marked;
multiset<ll> invs;
marked.insert({-1, inv});
marked.insert({n, 0});
invs.insert(inv);
rep(i, 0, n) {
ll p;
cin >> p;
p ^= ans.back();
--p;
auto it = marked.lower_bound({p, -1});
int r = it->first;
--it;
auto [l, inv] = *it;
marked.erase(it);
invs.erase(invs.find(inv));
ll invl = 0, invr = 0;
if (p - l < r - p) {
invr = inv;
rep(j, l + 1, p) {
invl += wm.rank_less(j + 1, p, a[j]);
invr -= wm.rank_less(p + 1, r, a[j]);
}
invr -= invl + wm.rank_greater(l + 1, p, a[p]) +
wm.rank_less(p + 1, r, a[p]);
} else {
invl = inv;
rep(j, p + 1, r) {
invr += wm.rank_less(j + 1, r, a[j]);
invl -= wm.rank_greater(l + 1, p, a[j]);
}
invl -= invr + wm.rank_greater(l + 1, p, a[p]) +
wm.rank_less(p + 1, r, a[p]);
}
marked.insert({l, invl});
marked.insert({p, invr});
invs.insert(invl);
invs.insert(invr);
ans.push_back(*invs.rbegin());
}
rep(i, 0, n) { cout << ans[i] << (i < n - 1 ? " " : "\n"); }
}
}
这程序好像有点Bug,我给组数据试试?
详细
Test #1:
score: 100
Accepted
time: 1ms
memory: 3704kb
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: 3125ms
memory: 20460kb
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