QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#222833#6631. Maximum Bitwise ORfickleTL 119ms59704kbC++205.9kb2023-10-21 19:05:392023-10-21 19:05:39

Judging History

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

  • [2023-10-21 19:05:39]
  • 评测
  • 测评结果:TL
  • 用时:119ms
  • 内存:59704kb
  • [2023-10-21 19:05:39]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define Mp make_pair
#define pb push_back
#define SZ(a) (int(a.size()))

typedef long long ll;
typedef double db;
typedef std::pair<int, int> pii;
typedef std::vector<int> vi;
#define log(...) fprintf(stderr, __VA_ARGS__)
std::mt19937_64 gen(std::chrono::system_clock::now().time_since_epoch().count());
ll get(ll l, ll r) { std::uniform_int_distribution<ll> dist(l, r); return dist(gen); }

const int N = 1e5 + 100;
const bool MIN = false, MAX = true;
const int Bsz = 30, inf = 2e9; // B = log(n)   block size
struct rmq { // O(n)-O(1) rmq   1e9
    int n, m, z[N], mn[20][N/20], pre[N], suf[N], stk[Bsz+10], bit[N];
    bool type; // Min or Max rmq   do Min rmq
    void prework() {
        int cur = inf;
        for(int i = 1; i <= n; i++) {
            if(i % Bsz == 0) cur = inf;
            cur = min(cur, z[i]), pre[i] = cur;
        }
        cur = inf;
        for(int i = n; i; i--) {
            cur = min(cur, z[i]), suf[i] = cur;
            if(i % Bsz == 0) cur = inf;
        }
        m = n / Bsz;
        for(int i = 0; i <= m; i++) mn[0][i] = inf;
        for(int i = 1; i <= n; i++) mn[0][i / Bsz] = min(mn[0][i / Bsz], z[i]);
        for(int k = 1; 1 << k <= m + 1; k++)
            for(int i = 0; i + (1 << k) - 1 <= m; i++)
                mn[k][i] = min(mn[k - 1][i], mn[k - 1][i + (1 << k - 1)]);
        int tp = 0, l = 0; cur = 0;
        for(int i = 1; i <= n; i++) {
            if(i % Bsz == 0) tp = cur = 0, l = i;
            while(tp && z[stk[tp]] >= z[i]) cur ^= 1 << (stk[tp] - l), tp--;
            bit[i] = cur ^= 1 << (i - l), stk[++tp] = i;
        }
    }
    void init(int arr[], int n_, bool type_) {
        // false for min, true for max
        n = n_, type = type_;
        for(int i = 1; i <= n; i++)
            z[i] = (type ? -arr[i] : arr[i]);
        prework();
    }
    int get_b(int l, int r) { // block min
        if(l > r) return inf;
        int x = 31 - __builtin_clz(r - l + 1); // log(r - l + 1)
        return min(mn[x][l], mn[x][r - (1 << x) + 1]);
    }
    int get(int l, int r) { // query min
        if(l / Bsz != r / Bsz) return min(get_b(l / Bsz + 1, r / Bsz - 1), min(suf[l], pre[r]));
        else return z[l + __builtin_ctz(bit[r] >> (l % Bsz))];
    }
    int query(int l, int r) { return type ? -get(l, r) : get(l, r); }
} qr[30];

int n, q, a[N], f[N][20], mx[N][20], rmx[30][N], nxt[N][30], pre[N][30], lg2[N];
int qor(int l, int r) {
    if(r < l) return 0;
    int lg = lg2[r - l + 1];
    return f[l][lg] | f[r - (1 << lg) + 1][lg];
}
int qmx(int l, int r) {
    if(r < l) return 0;
    int lg = lg2[r - l + 1];
    return max(mx[l][lg], mx[r - (1 << lg) + 1][lg]);
}
void solve() {
    cin >> n >> q;
    for(int i = 1; i <= n; i++) {
        cin >> a[i];
        f[i][0] = a[i];
        mx[i][0] = a[i];
        for(int j = 29, lst = -1; j >= 0; j--) {
            if(a[i] >> j & 1) lst = j;
            rmx[j][i] = lst;
        }
    }
    for(int i = 0; i < 30; i++) {
        qr[i].init(rmx[i], n, MAX);
    }
    for(int j = 1; 1 << j < n; j++)
        for(int i = 1; i + (1 << j) - 1 <= n; i++)
            f[i][j] = f[i][j - 1] | f[i + (1 << (j - 1))][j - 1],
            mx[i][j] = max(mx[i][j - 1], mx[i + (1 << (j - 1))][j - 1]);
    for(int i = 0; i < 30; i++) {
        nxt[n + 1][i] = n + 1;
    }
    for(int i = n; i; i--) {
        for(int j = 0; j < 30; j++)
            if(a[i] >> j & 1) nxt[i][j] = i;
            else nxt[i][j] = nxt[i + 1][j];
    }
    for(int i = 0; i < 30; i++) {
        pre[0][i] = 0;
    }
    for(int i = 1; i <= n; i++) {
        for(int j = 0; j < 30; j++)
            if(a[i] >> j & 1) pre[i][j] = i;
            else pre[i][j] = pre[i - 1][j];
    }
    while(q--) {
        int l, r;
        cin >> l >> r;
        int mxa = qmx(l, r), sumor = qor(l, r);
        int mxor = (1 << (32 - __builtin_clz(mxa))) - 1;
        auto getLR = [&](int x) {
            return Mp(__builtin_ctz(x), 31 - __builtin_clz(x));
        };
        auto [L, R] = getLR(sumor ^ mxor);
        if(sumor == mxor) {
            cout << mxor << " 0\n";
        } else {
            vi pos = {l - 1, r + 1};
            for(int nw = l, sum = 0; ; ) {
                int to = n + 1;
                for(int i = 0; i < 30; i++)
                    if((sum >> i & 1) == 0) to = min(to, nxt[nw][i]);
                if(to <= r) {
                    pos.pb(to);
                    nw = to;
                    sum ^= a[nw];
                } else break;
            }
            for(int nw = r, sum = 0; ; ) {
                int to = 0;
                for(int i = 0; i < 30; i++)
                    if((sum >> i & 1) == 0) to = max(to, pre[nw][i]);
                if(to >= l) {
                    pos.pb(to);
                    nw = to;
                    sum ^= a[nw];
                } else break;
            }
            sort(pos.begin(), pos.end());
            pos.erase(unique(pos.begin(), pos.end()), pos.end());
            int fl = 0;
            for(int i = 1; i < SZ(pos); i++) {
                int ll = pos[i - 1] + 1, rr = pos[i] - 1;
                if(rr < ll) continue;
                if(qr[L].query(ll, rr) >= R) fl = 1;
            }
            for(int i = 1; i + 1 < SZ(pos); i++) {
                int nowsum = qor(l, pos[i] - 1) | qor(pos[i] + 1, r);
                auto [nowL, nowR] = getLR(mxor ^ nowsum);
                if(rmx[nowL][pos[i]] >= nowR) fl = 1;
            }
            cout << mxor << ' ' << (fl ? 1 : 2) << '\n';
        }
    }
}
signed main() {
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    lg2[0] = -1;
    for(int i = 1; i < N; i++) lg2[i] = lg2[i >> 1] + 1;
    int _; cin >> _; for(int cas = 1; cas <= _; cas++) solve();
    cerr << "time: " << (db)clock()/CLOCKS_PER_SEC << "s\n";
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 59704kb

input:

1
3 2
10 10 5
1 2
1 3

output:

15 2
15 0

result:

ok 4 number(s): "15 2 15 0"

Test #2:

score: 0
Accepted
time: 119ms
memory: 59672kb

input:

100000
1 1
924704060
1 1
1 1
149840457
1 1
1 1
515267304
1 1
1 1
635378394
1 1
1 1
416239424
1 1
1 1
960156404
1 1
1 1
431278082
1 1
1 1
629009153
1 1
1 1
140374311
1 1
1 1
245014761
1 1
1 1
445512399
1 1
1 1
43894730
1 1
1 1
129731646
1 1
1 1
711065534
1 1
1 1
322643984
1 1
1 1
482420443
1 1
1 1
20...

output:

1073741823 2
268435455 2
536870911 2
1073741823 2
536870911 2
1073741823 2
536870911 2
1073741823 2
268435455 2
268435455 2
536870911 2
67108863 2
134217727 2
1073741823 2
536870911 2
536870911 2
268435455 2
536870911 2
536870911 2
536870911 2
268435455 2
268435455 2
1073741823 2
16777215 2
10737418...

result:

ok 200000 numbers

Test #3:

score: -100
Time Limit Exceeded

input:

50000
2 2
924896435 917026400
1 2
1 2
2 2
322948517 499114106
1 2
2 2
2 2
152908571 242548777
1 1
1 2
2 2
636974385 763173214
1 2
1 1
2 2
164965132 862298613
1 1
1 2
2 2
315078033 401694789
1 2
1 2
2 2
961358343 969300127
2 2
1 2
2 2
500628228 28065329
1 2
1 2
2 2
862229381 863649944
1 2
2 2
2 2
541...

output:


result: