QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#160477#7108. Couleurucup-team1600#AC ✓4062ms257964kbC++2010.6kb2023-09-02 20:32:522023-09-02 20:32:53

Judging History

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

  • [2023-09-02 20:32:53]
  • 评测
  • 测评结果:AC
  • 用时:4062ms
  • 内存:257964kb
  • [2023-09-02 20:32:52]
  • 提交

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