QOJ.ac

QOJ

ID提交记录ID题目HackerOwner结果提交时间测评时间
#365#160346#7108. Couleurucup-team1001ucup-team1447Failed.2023-09-04 18:26:482023-09-04 18:26:48

詳細信息

Extra Test:

Accepted
time: 3058ms
memory: 227152kb

input:

10
100000
100000 99999 99998 99997 99996 99995 99994 99993 99992 99991 99990 99989 99988 99987 99986 99985 99984 99983 99982 99981 99980 99979 99978 99977 99976 99975 99974 99973 99972 99971 99970 99969 99968 99967 99966 99965 99964 99963 99962 99961 99960 99959 99958 99957 99956 99955 99954 99953 9...

output:

4999950000 2800026361 2800026361 1079521345 793831935 793831935 793831935 490142395 436882020 436882020 436882020 436882020 402329161 402329161 402329161 402329161 402329161 402329161 402329161 402329161 402329161 402329161 402329161 402329161 402329161 402329161 402329161 402329161 402329161 402329...

result:

ok 10 lines

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#160346#7108. Couleurucup-team1447#AC ✓5042ms229836kbC++145.3kb2023-09-02 20:11:072023-09-02 20:11:08

answer

// This Code was made by Chinese_zjc_.
#include <bits/stdc++.h>
// #define debug
int L, T, N, n, m, a[200005], b[200005], sum[200005], in[200005], e[505][200005];
long long c[505], d[505][505], pre[200005], suf[200005];
std::pair<int, int> A[200005];
std::vector<int> rk[505];
void add(int pos, int val)
{
    while (pos <= n)
    {
        sum[pos] += val;
        pos += pos & -pos;
    }
}
int query(int pos)
{
    int res = 0;
    while (pos)
    {
        res += sum[pos];
        pos -= pos & -pos;
    }
    return res;
}
long long merge(const std::vector<int> &A, const std::vector<int> &B)
{
    long long res = 0;
    std::size_t Ai = 0, Bi = 0;
    while (Bi != B.size())
    {
        while (Ai != A.size() && A[Ai] < B[Bi])
            ++Ai;
        res += Ai;
        ++Bi;
    }
    return res;
}
long long merge1(const std::vector<int> &A, const std::vector<int> &B)
{
    long long res = 0;
    std::size_t Ai = 0, Bi = 0;
    while (Bi != B.size())
    {
        while (Ai != A.size() && A[Ai] < B[Bi])
            ++Ai;
        res += Ai;
        ++Bi;
    }
    return res;
}
long long merge2(const std::vector<int> &A, const std::vector<int> &B)
{
    long long res = 0;
    std::size_t Ai = 0, Bi = 0;
    while (Bi != B.size())
    {
        while (Ai != A.size() && A[Ai] < B[Bi])
            ++Ai;
        res += Ai;
        ++Bi;
    }
    return res;
}
long long query(int l, int r)
{
    static long long ans;
    static std::vector<int> A, B;
    A.clear(), B.clear();
    if (in[l] == in[r])
    {
        for (auto i : rk[in[l]])
            if (b[i] < l)
                A.push_back(i);
            else if (b[i] > r)
                B.push_back(i);
        ans = pre[r] + suf[l] + merge1(A, B) - c[in[l]] + c[in[l] - 1];
    }
    else
    {
        int L = in[l] + 1, R = in[r] - 1;
        ans = d[L][R] + c[R] - c[L - 1] + suf[l] + pre[r];
        for (int i = l; in[l] == in[i]; ++i)
            ans -= e[R][i] - e[L - 1][i];
        for (int i = r; in[r] == in[i]; --i)
            ans += e[R][i] - e[L - 1][i];
        for (auto i : rk[in[l]])
            if (b[i] >= l)
                A.push_back(i);
        for (auto i : rk[in[r]])
            if (b[i] <= r)
                B.push_back(i);
        ans += A.size() * (R - L + 1) * ::L;
        ans += merge2(A, B);
    }
    return ans;
}
signed main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cin >> T;
    while (T--)
    {
        std::cin >> N;
        n = N;
        L = std::min(375, N);
        for (int i = 1; i <= n; ++i)
            std::cin >> A[i].first, A[i].second = i;
        std::sort(A + 1, A + 1 + n);
        for (int i = 1; i <= n; ++i)
            a[A[i].second] = i;
        for (int i = 1; i <= n; ++i)
            a[i] = n - a[i] + 1;
        while (n % L)
            ++n, a[n] = n;
        for (int i = 1; i <= n; ++i)
            b[a[i]] = i;
        std::fill(sum, sum + 1 + n, 0);
        std::fill(in, in + 1 + n, 0);
        std::fill(pre, pre + 1 + n, 0);
        std::fill(suf, suf + 1 + n, 0);
        for (int i = 1; i <= n / L; ++i)
        {
            c[i] = 0;
            std::fill(d[i], d[i] + 1 + n / L, 0);
            std::fill(e[i], e[i] + 1 + n, 0);
            rk[i].clear();
        }
        for (int i = 1; i <= n / L; ++i)
        {
            int l = (i - 1) * L + 1, r = i * L;
            rk[i].resize(L);
            std::fill(in + l, in + r + 1, i);
            std::copy(a + l, a + r + 1, rk[i].begin());
            std::sort(rk[i].begin(), rk[i].end());
            std::copy(e[i - 1], e[i - 1] + n + 1, e[i]);
            for (int j = l; j <= r; ++j)
                ++e[i][a[j]];
            int tmp = 0;
            for (int j = l; j <= r; ++j)
            {
                tmp += query(a[j]);
                add(a[j], +1);
                pre[j] = tmp;
            }
            c[i] = tmp;
            for (int j = l; j <= r; ++j)
            {
                suf[j] = tmp;
                add(a[j], -1);
                tmp -= query(n) - query(a[j]);
            }
            c[i] += c[i - 1];
        }
        for (int i = 1; i <= n / L; ++i)
        {
            for (int j = 1; j <= n; ++j)
                e[i][j] += e[i][j - 1];
            int tmp[n + 1];
            for (int j = 1; j <= n; ++j)
                tmp[j] = e[i][a[j]];
            std::copy(tmp + 1, tmp + 1 + n, e[i] + 1);
        }
        for (int i = 1; i <= n / L; ++i)
            for (int j = i; --j;)
                d[j][i] = d[j + 1][i] + d[j][i - 1] - d[j + 1][i - 1] + merge(rk[j], rk[i]);
        std::multiset<long long> ans;
        std::set<int> del;
        del.insert(0);
        del.insert(N + 1);
        ans.insert(query(1, N));
        for (int i = 1; i <= N; ++i)
        {
            std::cout << *ans.rbegin() << " \n"[i == N];
            static long long c;
            std::cin >> c;
            c ^= *ans.rbegin();
            std::set<int>::iterator nxt = del.lower_bound(c), lst = std::prev(nxt);
            ans.erase(ans.find(query(*lst + 1, *nxt - 1)));
            if (*nxt - c > 1)
                ans.insert(query(c + 1, *nxt - 1));
            if (c - *lst > 1)
                ans.insert(query(*lst + 1, c - 1));
            del.insert(c);
        }
    }
    return 0;
}