[2015] Team largest mutual test and XOR

First, we do not know there is no god segment tree partition before.

First, a more obvious nature:

\ [\ Mathrm {Span} \ {v_1, v_2, \ dots, v_n \} = \ mathrm {Span} \ {v_1, v_2 - v_1, \ dots, v_n - v_ {n - 1} \} \]

This inspired us to maintain the difference sequence, then the operation becomes a single point of XOR, the second operation becomes a single point of the exclusive OR section and empty.

But this question is a linear-based maintenance, so use with linear base deletion achieve. (See in particular [2018] Team work around our circle )

At this single point XOR apparently can become re-insert deleted. Because of the time-based linear complexity, then empty the violence have no problem.

Because each makes up to two non-negative positions, empty vector determination Laid violence when emptied, can now be analyzed amortization, complexity correctly.

Thus complexity is \ (O (\ FRAC {(n-m +) mQ and {} \ Omega}) \) .

The optimized code base with linear deleted (from the great danger there some written reference)

#include <bits/stdc++.h>

const int MAXN = 2048;
typedef std::bitset<MAXN> B;
int n, m, Q;
B frm[MAXN], A[MAXN], arr[MAXN];
int bse[MAXN], isb[MAXN];
B read() {
    static B t; t.reset();
    static char buf[MAXN]; std::cin >> buf;
    for (int i = 1; i <= m; ++i) if (buf[i - 1] & 1) t.set(m - i + 1);
    return t;
}
void insert(int at) {
    for (int i = m; i; --i) if (A[at].test(i)) {
        if (bse[i]) A[at] ^= A[bse[i]], frm[at] ^= frm[bse[i]];
        else { isb[bse[i] = at] = i; break; }
    }
}
void modify(int at, B v) {
    if (v.none()) return ;
    int ax = 0; isb[0] = 2001;
    for (int i = 1; i <= n; ++i)
        if (frm[i].test(at))
            isb[i] < isb[ax] ? ax = i : 0;
    for (int i = 1; i <= n; ++i)
        if (i != ax && frm[i].test(at))
            A[i] ^= A[ax], frm[i] ^= frm[ax];
    if (isb[ax]) bse[isb[ax]] = 0, isb[ax] = 0;
    A[ax] ^= v, insert(ax);
}
void output(const B & x) {
    static char buf[MAXN];
    for (int i = 1; i <= m; ++i) buf[i - 1] = x[m - i + 1] + '0';
    std::cout << buf << std::endl;
}
B query() {
    static B t; t.reset();
    for (int i = m; i; --i)
        if (!t.test(i) && bse[i])
            t ^= A[bse[i]];
    return t;
}
int main() {
    std::ios_base::sync_with_stdio(false), std::cin.tie(0);
    std::cin >> n >> m >> Q;
    B t;
    for (int i = 1; i <= n; ++i)
        A[i] = (arr[i] = read()) ^ arr[i - 1], frm[i].set(i), insert(i);
    while (Q --> 0) {
        int opt, t1, t2;
        std::cin >> opt;
        if (opt == 1) {
            std::cin >> t1 >> t2; t = read();
            modify(t1, t);
            if (t2 < n) modify(t2 + 1, t);
            for (int i = t1; i <= t2; ++i) arr[i] ^= t;
        } else if (opt == 2) {
            std::cin >> t1 >> t2; t = read();
            modify(t1, arr[t1] ^ t);
            if (t2 < n) modify(t2 + 1, arr[t2] ^ t);
            for (int i = t1 + 1; i <= t2; ++i)
                modify(i, arr[i] ^ arr[i - 1]);
            for (int i = t1; i <= t2; ++i) arr[i] = t;
        } else if (opt == 3) output(query());
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/daklqw/p/11545965.html