pande22pic0103's blog

By pande22pic0103, history, 18 months ago, In English

Hi everyone,

I've recently started learning segment trees and was practicing with the problem: 339D — Xenia and Bit Operations.

I wrote the following C++ code to solve it. When I run the code locally using the CPH extension in VS Code, it works perfectly and gives the expected output for all test cases, including the one where it fails on Codeforces. However, when I submit the exact same code on Codeforces, it gives Wrong Answer on some test cases.

#include <bits/stdc++.h>
#include <ctype.h>
using namespace std;
#define int long long int
#define faster ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)

class Tree {
public:
    vector<int> seg;
    int lvl;
    string type;

    Tree(int n, int x) {
        seg.resize(4 * n + 1);
        if (x % 2) type = "or";
        else type = "xor";
    }

    void build(int ind, int lo, int hi, int arr[]) {
        if (lo == hi) {
            seg[ind] = arr[lo];
            return;
        }
        int mid = (lo + hi) >> 1;
        lvl++;
        build(2 * ind + 1, lo, mid, arr);
        build(2 * ind + 2, mid + 1, hi, arr);
        lvl--;

        if (type == "or") {
            if (lvl % 2) seg[ind] = seg[2 * ind + 1] ^ seg[2 * ind + 2];
            else seg[ind] = seg[2 * ind + 1] | seg[2 * ind + 2];
        } else {
            if (lvl % 2 == 0) seg[ind] = seg[2 * ind + 1] ^ seg[2 * ind + 2];
            else seg[ind] = seg[2 * ind + 1] | seg[2 * ind + 2];
        }
    }

    void update(int ind, int lo, int hi, int i, int val) {
        if (lo == hi) {
            seg[ind] = val;
            return;
        }
        int mid = (lo + hi) >> 1;
        lvl++;
        if (i <= mid) update(2 * ind + 1, lo, mid, i, val);
        else update(2 * ind + 2, mid + 1, hi, i, val);
        lvl--;

        if (type == "or") {
            if (lvl % 2) seg[ind] = seg[2 * ind + 1] ^ seg[2 * ind + 2];
            else seg[ind] = seg[2 * ind + 1] | seg[2 * ind + 2];
        } else {
            if (lvl % 2 == 0) seg[ind] = seg[2 * ind + 1] ^ seg[2 * ind + 2];
            else seg[ind] = seg[2 * ind + 1] | seg[2 * ind + 2];
        }
    }
};

void solve() {
    int n, q;
    cin >> n >> q;
    int x = n;
    n = 1 << n;
    int arr[n];
    for (int i = 0; i < n; i++) cin >> arr[i];
    Tree tree(n, x);
    tree.build(0, 0, n - 1, arr);

    while (q--) {
        int i, val;
        cin >> i >> val;
        i--;
        tree.lvl = 0;
        tree.update(0, 0, n - 1, i, val);
        cout << tree.seg[0] << endl;
    }
}

int32_t main() {
    solve();
    return 0;
}

I would be really grateful if someone could help me understand:

Is the problem with my code, or is it something related to compiler behavior on Codeforces?

Why does the same code behave correctly locally but gives WA on Codeforces?

Any suggestions or corrections are welcome. Thank you!

  • Vote: I like it
  • -5
  • Vote: I do not like it

| Write comment?
»
18 months ago, hide # |
← Rev. 2  
Vote: I like it 0 Vote: I do not like it

I might be wrong, but are you sure a size of $$$4n+1$$$ is enough? You're propagating with $$$2n+1$$$ and $$$2n+2$$$ (already quite nonstandard) so I suspect you'll need a bigger size.

Anyways, I'm 99% sure your code goes out of bounds somewhere and therefore has undefined behaviour. Try running it with an address sanitizer or something like valgrind if this doesn't fix your issue.

(By the way, you really should use left child is $$$2v$$$ and right child is $$$2v+1$$$, at least in my opinion)

»
18 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

try this: https://codeforces.me/blog/entry/15547

most probably locally you run your code with no flags (while codeforces does enable some optimization and sanitizers)