社区讨论

卡常求助 90pts

P5795[THUSC 2015] 异或运算参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lz2i8fru
此快照首次捕获于
2024/07/26 17:33
2 年前
此快照最后确认于
2024/07/26 19:03
2 年前
查看原帖
最后一个点 TLE
CPP
#include <bits/stdc++.h>
using namespace std;
inline int read()
{
    int ans = 0, f = 0;
    char c = getchar();
    while (!isdigit(c))
        f |= (c == '-'), c = getchar();
    while (isdigit(c))
        ans = (ans << 3) + (ans << 1) + c - 48, c = getchar();
    return f ? -ans : ans;
}
void write(int x)
{
    if (x < 0)
        putchar('-'), x = -x;
    if (x > 9)
        write(x / 10);
    putchar(48 + x % 10);
}
const int N = 3e5 + 5, M = N * 40;
int n, m, q, a[N], b[M];
struct Trie
{
    int cnt, root[N], si[M], son[M][2];
    inline int clone(int p)
    {
        si[++cnt] = si[p], son[cnt][0] = son[p][0], son[cnt][1] = son[p][1];
        return cnt;
    }
    inline int Insert(int p, int x)
    {
        int res = (p = clone(p));
        ++si[p];
        for (int j = 30; j >= 0; --j)
        {
            int i = x >> j & 1;
            son[p][i] = clone(son[p][i]);
            ++si[p = son[p][i]];
        }
        return res;
    }
    inline int Ask(int p1, int p2, int ad, int k)
    {
        int ans = 0;
        for (int j = 30; j >= 0; --j)
        {
            int i = (ad >> j & 1) ^ 1, now = k >> j & 1;
            if (now == 0)
                ans += si[son[p2][i]] - si[son[p1][i]],
                    p1 = son[p1][i ^ 1], p2 = son[p2][i ^ 1];
            else
                p1 = son[p1][i], p2 = son[p2][i];
        }
        return ans;
    }
    inline void insert(int i, int x) { root[i] = Insert(root[i - 1], x); }
    inline int ask(int l, int r, int ad, int x) { return Ask(root[l - 1], root[r], ad, x); }
} trie;
inline int solve(int u, int d, int l, int r, int k)
{
    int ans = 0;
    for (int i = u; i <= d; ++i)
        ans += trie.ask(l, r, a[i], k);
    return ans;
}
signed main()
{
    // freopen(".silver_in", "r", stdin);
    // freopen(".silver_out", "w", stdout);
    n = read(), m = read();
    for (int i = 1; i <= n; ++i)
        a[i] = read();
    for (int i = 1; i <= m; ++i)
        trie.insert(i, b[i] = read());
    q = read();
    while (q--)
    {
        int u = read(), d = read(), L = read(), R = read(), k = read();
        int l = 0, r = INT_MAX, ans = -1;
        while (l <= r)
        {
            int mid = (1ll * l + r) / 2;
            if (solve(u, d, L, R, mid) < k)
                ans = mid, r = mid - 1;
            else
                l = mid + 1;
        }
        write(ans), putchar('\n');
    }
    return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...