QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#160477 | #7108. Couleur | ucup-team1600# | AC ✓ | 4062ms | 257964kb | C++20 | 10.6kb | 2023-09-02 20:32:52 | 2023-09-02 20:32:53 |
Judging History
answer
//#pragma GCC optimize("Ofast", "unroll-loops")
//#pragma GCC target("sse", "sse2", "sse3", "ssse3", "sse4")
#ifdef __APPLE__
#include <iostream>
#include <cmath>
#include <algorithm>
#include <stdio.h>
#include <cstdint>
#include <cstring>
#include <string>
#include <cstdlib>
#include <vector>
#include <bitset>
#include <map>
#include <queue>
#include <ctime>
#include <stack>
#include <set>
#include <list>
#include <random>
#include <deque>
#include <functional>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <complex>
#include <numeric>
#include <cassert>
#include <array>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <thread>
#else
#include <bits/stdc++.h>
#endif
#define all(a) a.begin(),a.end()
#define len(a) (int)(a.size())
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
#define fi first
#define se second
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;
template<typename T>
bool umin(T &a, T b) {
if (b < a) {
a = b;
return true;
}
return false;
}
template<typename T>
bool umax(T &a, T b) {
if (a < b) {
a = b;
return true;
}
return false;
}
#if __APPLE__
#define D for (bool _FLAG = true; _FLAG; _FLAG = false)
#define LOG(...) print(#__VA_ARGS__" ::", __VA_ARGS__) << endl
template<class ...Ts>
auto &print(Ts ...ts) { return ((cerr << ts << " "), ...); }
#else
#define D while (false)
#define LOG(...)
#endif
const int max_n = 1e5 + 42, block = 666, am_blocks = max_n / block + 3, inf = 1000111222;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
namespace fastio {
const int buf_size = 1 << 14, small = 30;
char buf_read[buf_size + small];
char buf_write[buf_size + small];
char *ptr_read = buf_read + buf_size;
char *ptr_write = buf_write;
char getChar() {
if (ptr_read == buf_read + buf_size){
buf_read[fread(buf_read, 1, buf_size, stdin)] = 0;
ptr_read = buf_read;
}
return *ptr_read++;
};
inline bool is_whitespace(char c) {
return c == ' ' || c == '\r' || c == '\n';
}
char read_char() {
char c = getChar();
while (is_whitespace(c)) {
c = getChar();
}
return c;
}
string read_string() {
string res;
char c = read_char();
do {
res += c;
c = getChar();
} while (c && !is_whitespace(c));
return res;
}
long long read_int() {
char c = getChar();
while (c && (c < '0' || c > '9') && c != '-') {
c = getChar();
}
long long z = 1;
if (c == '-') {
z = -1;
c = getChar();
}
long long res = 0;
while (c >= '0' && c <= '9'){
res = res * 10 + (c - '0');
c = getChar();
}
return z * res;
}
void write_flush() {
fwrite(buf_write, 1, ptr_write - buf_write, stdout);
ptr_write = buf_write;
}
void write_int(long long x) {
if (x < 0) {
*ptr_write++ = '-';
x = -x;
}
char *start = ptr_write;
if (!x) {
*ptr_write++ = '0';
}
while (x) {
*ptr_write++ = x % 10 + '0';
x /= 10;
}
reverse(start, ptr_write);
if (ptr_write >= buf_write + buf_size) {
write_flush();
}
}
void write_char(char c) {
*ptr_write++ = c;
if (ptr_write >= buf_write + buf_size) {
write_flush();
}
}
void write_string(const string &s) {
for (char c : s) {
write_char(c);
}
}
}
struct fenw1 {
int fw[max_n];
void add(int k, int x) {
for(k++; k > 0; k -= (k & -k)) fw[k] += x;
}
int get(int k) {
int res = 0;
for(k++; k < max_n; k += (k & -k)) res += fw[k];
return res;
}
} fw1;
struct fenw2 {
int fw[max_n];
void add(int k, int x) {
for(k++; k < max_n; k += (k & -k)) fw[k] += x;
}
int get(int k) {
int res = 0;
for(k++; k > 0; k -= (k & -k)) res += fw[k];
return res;
}
} fw2;
ll invL[am_blocks][max_n], invR[am_blocks][max_n];
vector<pair<int, int> > in_block[am_blocks];
vector<pair<int, int> > b;
int n;
int a[max_n], p[max_n];
int blocknum[max_n], L_ind[max_n], R_ind[max_n];
bool isL[max_n], isR[max_n];
set<int> blocked;
void precalc() {
for(int i = 0, j = 1; i < n; i += block, j++) {
in_block[j].clear();
int i2 = min(n - 1, i + block - 1);
for(int k = i; k <= i2; k++) {
in_block[j].pb({a[k], k});
isL[k] = isR[k] = false;
blocknum[k] = j;
}
sort(all(in_block[j]));
L_ind[j] = i;
R_ind[j] = i2;
isL[i] = true;
isR[i2] = true;
}
b.clear();
for(int i = 0; i < n; i++) b.pb({a[i], i});
sort(all(b));
for(int i = 0; i < n; i++) {
if(isR[i]) {
int cblock = blocknum[i];
int i2 = L_ind[cblock];
fw2.add(a[i], 1);
for(int j = i - 1; j >= i2; j--) {
invR[cblock][j] = invR[cblock][j + 1] + fw2.get(a[j] - 1);
fw2.add(a[j], 1);
}
for(int j = i; j >= i2; j--) fw2.add(a[j], -1);
int posbl = 0, kek = len(in_block[cblock]);
for(auto& x : b) {
while(posbl < kek && x.fi > in_block[cblock][posbl].fi) {
posbl++;
}
if(x.se < i2) invR[cblock][x.se] += posbl;
}
for(int j = i2 - 1; j >= 0; j--) {
invR[cblock][j] += invR[cblock][j + 1] + invR[cblock - 1][j] - invR[cblock - 1][j + 1];
}
i += block - 1;
}
}
for(int i = n - 1; i >= 0; i--) {
if(isL[i]) {
int cblock = blocknum[i];
int i2 = R_ind[cblock];
fw1.add(a[i], 1);
for(int j = i + 1; j <= i2; j++) {
invL[cblock][j] = invL[cblock][j - 1] + fw1.get(a[j] + 1);
fw1.add(a[j], 1);
}
for(int j = i; j <= i2; j++) fw1.add(a[j], -1);
int posbl = 0, kek = len(in_block[cblock]);
for(auto& x : b) {
while(posbl < kek && x.fi >= in_block[cblock][posbl].fi) {
posbl++;
}
if(x.se > i2) invL[cblock][x.se] += kek - posbl;
}
for(int j = i2 + 1; j < n; j++) {
invL[cblock][j] += invL[cblock][j - 1] + invL[cblock + 1][j] - invL[cblock + 1][j - 1];
}
i -= block - 1;
}
}
}
ll get_on_borders(int l1, int r1, int l2, int r2) {
if(r1 < l1 || r2 < l2) return 0;
// cout << l1 << ' ' << r1 << ' ' << l2 << ' ' << r2 << 't' << endl;
int block1 = blocknum[l1], block2 = blocknum[l2];
ll res = 0;
int pos2 = 0, am2 = 0, kek = len(in_block[block2]);
for(auto& x : in_block[block1]) {
while(pos2 < kek && in_block[block2][pos2].fi < x.fi) {
am2 += (l2 <= in_block[block2][pos2].se && in_block[block2][pos2].se <= r2);
pos2++;
}
if(l1 <= x.se && x.se <= r1) res += am2;
}
return res;
}
map<pair<int, int>, ll> hmm;
ll get_inv(int l, int r) {
auto it = hmm.find({l, r});
if(it != hmm.end()) return it->se;
ll res = 0;
if(blocknum[l] == blocknum[r]) {
int cblock = blocknum[l];
int cL = L_ind[cblock];
res += invL[cblock][r];
res -= invL[cblock][l - 1];
res -= get_on_borders(cL, l - 1, l, r);
return hmm[{l, r}] = res;
} else {
int L3 = R_ind[blocknum[l]] + 1, R3 = L_ind[blocknum[r]] - 1;
res += invL[blocknum[L3]][r] + invR[blocknum[R3]][l] - invL[blocknum[L3]][R3];
res += get_on_borders(l, L3 - 1, R3 + 1, r);
}
return hmm[{l, r}] = res;
}
multiset<ll> av;
bool RNG = false;
void solve() {
hmm.clear();
blocked.clear();
if(RNG) {
// n = fastio::read_int();
n = 100000;
} else {
n = fastio::read_int();
}
int cam_blocks = n / block + 3;
for(int i = 0; i < cam_blocks; i++)
for(int j = 0; j < n; j++)
invL[i][j] = invR[i][j] = 0;
blocked.insert(-1); blocked.insert(n);
if(RNG) {
for(int i = 0; i < n; i++) a[i] = rng() % n + 1;
} else {
for (int i = 0; i < n; i++) a[i] = fastio::read_int();
for (int i = 0; i < n; i++) p[i] = fastio::read_int();
}
precalc();
av.clear();
av.insert(get_inv(0, n - 1));
av.insert(0);
ll z = (*av.rbegin());
vector<int> ord(n);
iota(all(ord), 0);
shuffle(all(ord), rng);
// for(auto& x : ord) cout << x << ' ';
// cout << endl;
for(int i = 0; i < n; i++) {
if(i) fastio::write_char(' ');
fastio::write_int(z);
// cout << z;
// cout << endl;
int cpos;
if(RNG) cpos = ord[i];
else {
cpos = (int) (p[i] ^ z);
cpos--;
}
// cout << cpos << ' ' << p[i] << ' ' << z << endl;
auto it = blocked.lower_bound(cpos);
int nxt = (*it);
it--;
int prv = (*it);
nxt--; prv++;
blocked.insert(cpos);
av.erase(av.find(get_inv(prv, nxt)));
if(cpos + 1 <= nxt) {
av.insert(get_inv(cpos + 1, nxt));
// cout << cpos + 1 << ' ' << nxt << ' ' << get_inv(cpos + 1, nxt) << '\n';
}
if(prv <= cpos - 1) {
av.insert(get_inv(prv, cpos - 1));
// cout << prv << ' ' << cpos - 1 << ' ' << get_inv(prv, cpos - 1) << '\n';
}
z = (*av.rbegin());
}
fastio::write_char('\n');
// cout << '\n';
}
signed main() {
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t = fastio::read_int();
// cin >> t;
while (t--) solve();
fastio::write_flush();
}
/*
KIVI
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
*/
这程序好像有点Bug,我给组数据试试?
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 2ms
memory: 9868kb
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: 4062ms
memory: 257964kb
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