Submission #564812

#TimeUsernameProblemLanguageResultExecution timeMemory
564812StickfishIntergalactic ship (IZhO19_xorsum)C++17
92 / 100
2083 ms4032 KiB
#include <iostream>
#include <vector>
#include <map>
#include <bitset>
#include <cassert>
using namespace std;
using ll = long long;
using ull = unsigned long long;

const int MAXN = 1008;
const ll MOD = 1000000007;
const int MAXVAL = 128;
const int HEY = MAXVAL * 3;
int a[MAXN];


void updt(bitset<MAXVAL>& bs, int t) {
    if (bs[t])
        return;
    int sz = bs.count();
    for (int i = 0; i < MAXVAL;) {
        if (bs[i])
            bs[i ^ t] = bs[i];
        if (sz <= 8)
            i = bs._Find_next(i);
        else
            ++i;
    }
}

bitset<MAXVAL> xorbs(bitset<MAXVAL>& bs, int t) {
    bitset<MAXVAL> ans;
    for (int i = 0; i < MAXVAL; ++i)
        ans[i ^ t] = bs[i];
    return ans;
}

ll pw(ll a, ll m) {
    if (!m)
        return 1;
    a %= MOD;
    if (m % 2)
        return a * pw(a, m - 1) % MOD;
    return pw(a * a, m / 2);
}

bool in(pair<int, int> sg, int i) {
    return sg.first <= i && i < sg.second;
}

int chg[128];

bitset<MAXVAL> get_bs(bitset<MAXVAL> genbs) {
    for (int bt = 1; bt < 128; bt *= 2) {
        for (int x = bt; x < 128; x += bt * 2) {
            if (genbs[x]) {
                for (int y = bt; y < 128; y += bt * 2) {
                    if (y != x && genbs[y]) {
                        genbs[y ^ x] = 1;
                        genbs[y] = 0;
                    }
                }
                break;
            }
        }
    }
    genbs[0] = 0;
    int t = genbs.count();
    bitset<MAXVAL> ans;
    if (t == 0) {
        ans[0] = 1;
        return ans;
    }
    vector<int> prefxor(t);
    int tmp = genbs._Find_first();
    for (int i = 0; i < t; ++i) {
        prefxor[i] = tmp;
        if (i)
            prefxor[i] ^= prefxor[i - 1];
        tmp = genbs._Find_next(tmp);
    }
    //for (int i = 0; i < (1 << t); ++i)
        //cout << chg[i] << ' ';
    //cout << endl;
    int x = 0;
    ans[0] = 1;
    for (int msk = 1; msk < (1 << t); ++msk) {
        x ^= prefxor[chg[msk - 1]];
        ans[x] = 1;
    }
    return ans;
}

vector<pair<int, int>> events[MAXN];
int change_ij[MAXN][MAXVAL];
int change_i[MAXN][MAXVAL];
int change_j[MAXN][MAXVAL];

struct sixple {
    ull first;
    ull second;
    ull third;
    ull fourth;
    ull fifth;
    ull sixth;

    bool operator<(sixple& s) {
        if (first != s.first)
            return first < s.first;
        if (second != s.second)
            return second < s.second;
        if (third != s.third)
            return third < s.third;
        if (fourth != s.fourth)
            return fourth < s.fourth;
        if (fifth != s.fifth)
            return fifth < s.fifth;
        return sixth < s.sixth;
    }
};

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int tmp = 1;
    for (int bt = 2; bt <= 128; bt *= 2) {
        for (int i = bt; i <= 128; i += bt * 2) {
            chg[i - 1] = tmp;
        }
        ++tmp;
    }
    //for (int i = 0; i < 128; ++i)
        //cout << chg[i] << ' ';
    //cout << endl;
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i)
        cin >> a[i];
    int q;
    cin >> q;
    for (int i = 0; i < q; ++i) {
        int l, r, x;
        cin >> l >> r >> x;
        --l;
        events[l].push_back({r, x});
        events[r].push_back({l, x});
        ++change_j[l][x];
        --change_j[r][x];
    }
    ll ans = 0;
    vector<int> genij0(MAXVAL, 0);
    bitset<MAXVAL> genbsij0;
    for (int i = 0; i < n; ++i) {
        for (auto [e, x] : events[i]) {
            if (e < i)
                genbsij0[x] = --genij0[x];
            else {
                genbsij0[x] = ++genij0[x];
                --change_ij[e][x];
                ++change_j[e][x];
                ++change_i[e][x];
            }
        }
        vector<int> geni(MAXVAL);
        bitset<MAXVAL> genbsi;
        vector<int> genj(MAXVAL);
        bitset<MAXVAL> genbsj;
        vector<int> genij = genij0;
        bitset<MAXVAL> genbsij = genbsij0;

        for (int j = i; j < n; ++j) {
            if (j > i) {
                for (int x = 0; x < 128; ++x) {
                    genbsij[x] = (genij[x] += change_ij[j][x]);
                    genbsi[x] = (geni[x] += change_i[j][x]);
                    genbsj[x] = (genj[x] += change_j[j][x]);
                }
            }
            bitset<MAXVAL> bsi = get_bs(genbsi);
            bitset<MAXVAL> bsj = get_bs(genbsj);
            bitset<MAXVAL> bsij = get_bs(genbsij);
            bsi = xorbs(bsi, a[i]);
            bsj = xorbs(bsj, a[j]);
            ll addans = 0;
            //ans += bsi.count() + bsj.count() + bsij.count();
            //continue;
            if (bsij.count() == 128 && (bsi.count() == 128 || bsj.count() == 128)) {
                if (bsi.count() == 128) {
                    addans += 64ll * 127 * 64 * 127 * bsj.count();
                } else {
                    addans += 64ll * 127 * 64 * 127 * bsi.count();
                }
            } else {
                vector<int> xj_from_xij(MAXVAL);
                for (int xij = bsij._Find_first(); xij < MAXVAL; xij = bsij._Find_next(xij)) {
                    if (bsj.count() == 128) {
                        xj_from_xij[xij] = 64 * 127;
                    } else {
                        for (int xj = bsj._Find_first(); xj < MAXVAL; xj = bsj._Find_next(xj)) {
                            xj_from_xij[xij] += xj ^ xij;
                        }
                    }
                }
                for (int xij = bsij._Find_first(); xij < MAXVAL; xij = bsij._Find_next(xij)) {
                    if (bsi.count() == 128) {
                        addans += xj_from_xij[xij] * 64 * 127;
                    } else {
                        for (int xi = bsi._Find_first(); xi < MAXVAL; xi = bsi._Find_next(xi)) {
                            addans += xj_from_xij[xij] * (xi ^ xij);
                        }
                    }
                    addans %= MOD;
                }
            }
            if (i != j) {
                addans *= 2;
            }
            addans *= (i + 1) * (n - j);
            addans %= MOD;
            addans *= pw(2, q);
            addans %= MOD;
            addans *= pw(bsi.count() * bsj.count() * bsij.count(), MOD - 2);
            ans += addans;
            ans %= MOD;
        }
    }
    cout << ans << endl;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...