QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#245522#7765. Xor Masterhos_lyric#0 383ms295720kbC++1410.2kb2023-11-09 23:56:272024-07-04 02:23:50

Judging History

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

  • [2024-07-04 02:23:50]
  • 评测
  • 测评结果:0
  • 用时:383ms
  • 内存:295720kb
  • [2023-11-09 23:56:27]
  • 提交

answer

#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

using Int = long long;

template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
#define COLOR(s) ("\x1b[" s "m")

// T: monoid representing information of an interval.
//   T()  should return the identity.
//   T(S s)  should represent a single element of the array.
//   T::push(T &l, T &r)  should push the lazy update.
//   T::pull(const T &l, const T &r)  should pull two intervals.
template <class T> struct SegmentTreeRange {
  int logN, n;
  vector<T> ts;
  SegmentTreeRange() : logN(0), n(0) {}
  explicit SegmentTreeRange(int n_) {
    for (logN = 0, n = 1; n < n_; ++logN, n <<= 1) {}
    ts.resize(n << 1);
  }
  template <class S> explicit SegmentTreeRange(const vector<S> &ss) {
    const int n_ = ss.size();
    for (logN = 0, n = 1; n < n_; ++logN, n <<= 1) {}
    ts.resize(n << 1);
    for (int i = 0; i < n_; ++i) at(i) = T(ss[i]);
    build();
  }
  T &at(int i) {
    return ts[n + i];
  }
  void build() {
    for (int u = n; --u; ) pull(u);
  }

  inline void push(int u) {
    ts[u].push(ts[u << 1], ts[u << 1 | 1]);
  }
  inline void pull(int u) {
    ts[u].pull(ts[u << 1], ts[u << 1 | 1]);
  }

  // Applies T::f(args...) to [a, b).
  template <class F, class... Args>
  void ch(int a, int b, F f, Args &&... args) {
    assert(0 <= a); assert(a <= b); assert(b <= n);
    if (a == b) return;
    a += n; b += n;
    for (int h = logN; h; --h) {
      const int aa = a >> h, bb = b >> h;
      if (aa == bb) {
        if ((aa << h) != a || (bb << h) != b) push(aa);
      } else {
        if ((aa << h) != a) push(aa);
        if ((bb << h) != b) push(bb);
      }
    }
    for (int aa = a, bb = b; aa < bb; aa >>= 1, bb >>= 1) {
      if (aa & 1) (ts[aa++].*f)(args...);
      if (bb & 1) (ts[--bb].*f)(args...);
    }
    for (int h = 1; h <= logN; ++h) {
      const int aa = a >> h, bb = b >> h;
      if (aa == bb) {
        if ((aa << h) != a || (bb << h) != b) pull(aa);
      } else {
        if ((aa << h) != a) pull(aa);
        if ((bb << h) != b) pull(bb);
      }
    }
  }

  // Calculates the product for [a, b).
  T get(int a, int b) {
    assert(0 <= a); assert(a <= b); assert(b <= n);
    if (a == b) return T();
    a += n; b += n;
    for (int h = logN; h; --h) {
      const int aa = a >> h, bb = b >> h;
      if (aa == bb) {
        if ((aa << h) != a || (bb << h) != b) push(aa);
      } else {
        if ((aa << h) != a) push(aa);
        if ((bb << h) != b) push(bb);
      }
    }
    T prodL, prodR, t;
    for (int aa = a, bb = b; aa < bb; aa >>= 1, bb >>= 1) {
      if (aa & 1) { t.pull(prodL, ts[aa++]); prodL = t; }
      if (bb & 1) { t.pull(ts[--bb], prodR); prodR = t; }
    }
    t.pull(prodL, prodR);
    return t;
  }

  // Calculates T::f(args...) of a monoid type for [a, b).
  //   op(-, -)  should calculate the product.
  //   e()  should return the identity.
  template <class Op, class E, class F, class... Args>
#if __cplusplus >= 201402L
  auto
#else
  decltype((std::declval<T>().*F())())
#endif
  get(int a, int b, Op op, E e, F f, Args &&... args) {
    assert(0 <= a); assert(a <= b); assert(b <= n);
    if (a == b) return e();
    a += n; b += n;
    for (int h = logN; h; --h) {
      const int aa = a >> h, bb = b >> h;
      if (aa == bb) {
        if ((aa << h) != a || (bb << h) != b) push(aa);
      } else {
        if ((aa << h) != a) push(aa);
        if ((bb << h) != b) push(bb);
      }
    }
    auto prodL = e(), prodR = e();
    for (int aa = a, bb = b; aa < bb; aa >>= 1, bb >>= 1) {
      if (aa & 1) prodL = op(prodL, (ts[aa++].*f)(args...));
      if (bb & 1) prodR = op((ts[--bb].*f)(args...), prodR);
    }
    return op(prodL, prodR);
  }

  // Find min b s.t. T::f(args...) returns true,
  // when called for the partition of [a, b) from left to right.
  //   Returns n + 1 if there is no such b.
  template <class F, class... Args>
  int findRight(int a, F f, Args &&... args) {
    assert(0 <= a); assert(a <= n);
    if ((T().*f)(args...)) return a;
    if (a == n) return n + 1;
    a += n;
    for (int h = logN; h; --h) push(a >> h);
    for (; ; a >>= 1) if (a & 1) {
      if ((ts[a].*f)(args...)) {
        for (; a < n; ) {
          push(a);
          if (!(ts[a <<= 1].*f)(args...)) ++a;
        }
        return a - n + 1;
      }
      ++a;
      if (!(a & (a - 1))) return n + 1;
    }
  }

  // Find max a s.t. T::f(args...) returns true,
  // when called for the partition of [a, b) from right to left.
  //   Returns -1 if there is no such a.
  template <class F, class... Args>
  int findLeft(int b, F f, Args &&... args) {
    assert(0 <= b); assert(b <= n);
    if ((T().*f)(args...)) return b;
    if (b == 0) return -1;
    b += n;
    for (int h = logN; h; --h) push((b - 1) >> h);
    for (; ; b >>= 1) if ((b & 1) || b == 2) {
      if ((ts[b - 1].*f)(args...)) {
        for (; b <= n; ) {
          push(b - 1);
          if (!(ts[(b <<= 1) - 1].*f)(args...)) --b;
        }
        return b - n - 1;
      }
      --b;
      if (!(b & (b - 1))) return -1;
    }
  }
};

////////////////////////////////////////////////////////////////////////////////

using U = unsigned long long;
constexpr int E = 64;
int LEN;

struct Node {
  int sz, cnt[E];
  U lz;
  Node() : sz(0), cnt{}, lz(0) {}
  void push(Node &l, Node &r) {
    if (lz) {
      l.flip(lz);
      r.flip(lz);
      lz = 0;
    }
  }
  void pull(const Node &l, const Node &r) {
    sz = l.sz + r.sz;
    for (int k = 0; k < LEN; ++k) {
      cnt[k] = l.cnt[k] + r.cnt[k];
    }
  }
  void flip(U val) {
    for (int k = 0; k < LEN; ++k) if (val >> k & 1) {
      cnt[k] = sz - cnt[k];
    }
  }
};

int N, Q;
vector<U> A;
vector<int> O, L, R;
vector<U> V;

int main() {
  for (; ~scanf("%d%d", &N, &Q); ) {
    A.resize(N);
    for (int i = 0; i < N; ++i) {
      scanf("%llu", &A[i]);
    }
    O.assign(Q, -1);
    L.assign(Q, -1);
    R.assign(Q, -1);
    V.assign(Q, 0);
    for (int q = 0; q < Q; ++q) {
      scanf("%d", &O[q]);
      if (O[q] == 1) {
        scanf("%d%llu", &L[q], &V[q]);
        --L[q];
      } else if (O[q] == 2) {
        scanf("%llu", &V[q]);
      } else if (O[q] == 3) {
        scanf("%d%d", &L[q], &R[q]);
        --L[q];
        --R[q];
      } else {
        assert(false);
      }
    }
    
    vector<U> bit(N, 0);
    vector<U> ASum(N + 1, 0);
    SegmentTreeRange<Node> seg(N + 1);
    
    U basis[E] = {}, effects[E] = {}, masks[E] = {};
    int es[E] = {};
    auto build = [&]() -> void {
      for (int i = 0; i < N; ++i) {
        bit[i] = A[i];
      }
      for (int i = 0; i < N; ++i) {
        const int ii = i | (i + 1);
        if (ii < N) {
          bit[ii] ^= bit[i];
        }
      }
      for (int i = 0; i < N; ++i) {
        ASum[i + 1] = ASum[i] ^ A[i];
      }
      U on = 0;
      for (int e = 0; e < E; ++e) if (basis[e]) {
        on |= 1ULL << e;
      }
      LEN = 0;
      fill(effects, effects + E, 0);
      for (int e = 0; e < E; ++e) if (!basis[e]) {
        // modified[e] = original[e] \oplus (\bigoplus[f] (1 \oplus original[f])
        const int k = LEN++;
        effects[e] |= 1ULL << k;
        U mask = 1ULL << e;
        for (int f = e + 1; f < E; ++f) if (basis[f] >> e & 1) {
          effects[f] |= 1ULL << k;
          mask |= 1ULL << f;
        }
        es[k] = e;
        masks[k] = mask;
      }
// cerr<<"basis = ";pv(basis,basis+E);
// cerr<<"es = ";pv(es,es+LEN);
// cerr<<"masks = ";pv(masks,masks+LEN);
      for (int i = 0; i <= N; ++i) {
        auto &f = seg.at(i);
        f.sz = 1;
        f.lz = 0;
        for (int k = 0; k < LEN; ++k) {
          f.cnt[k] = __builtin_parityll((ASum[i] ^ on) & masks[k]);
        }
// cerr<<ASum[i]<<": ";pv(f.cnt,f.cnt+LEN);
      }
      seg.build();
    };
    build();
    for (int q = 0; q < Q; ++q) {
      if (O[q] == 1) {
        A[L[q]] ^= V[q];
        U val = 0;
        for (int e = 0; e < E; ++e) if (V[q] >> e & 1) {
          val ^= effects[e];
        }
        seg.ch(L[q] + 1, N + 1, &Node::flip, val);
      } else if (O[q] == 2) {
        U v = V[q];
        for (int e = 0; e < E; ++e) {
          chmin(v, v ^ basis[e]);
        }
        if (v) {
          const int e0 = 63 - __builtin_clzll(v);
          for (int e = 0; e < E; ++e) if (basis[e] >> e0 & 1) {
            basis[e] ^= v;
          }
          basis[e0] = v;
        }
        build();
      } else if (O[q] == 3) {
        U al = 0;
        for (int i = L[q]; i; i &= i - 1) {
          al ^= bit[i - 1];
        }
        auto res = seg.get(L[q] + 1, R[q] + 2);
        U val = 0;
        for (int e = 0; e < E; ++e) if (al >> e & 1) {
          val ^= effects[e];
        }
        res.flip(val);
// cerr<<"al = "<<al<<", val = "<<val<<endl;
        U ans = 0;
        for (int e = 0; e < E; ++e) if (basis[e]) {
          ans += ((U)res.sz << e);
        }
        for (int k = 0; k < LEN; ++k) {
          ans += ((U)res.cnt[k] << es[k]);
        }
        printf("%lld\n", ans);
      } else {
        assert(false);
      }
    }
  }
  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Subtask #1:

score: 0
Wrong Answer

Test #1:

score: 0
Wrong Answer
time: 41ms
memory: 4496kb

input:

2000 2000
1860495733 462603674 3739839441 759356520 47330263 550811730 2301200895 989240351 2499503801 2624225494 2123076812 1180966826 238739434 488666688 784742950 2583466952 4111371941 2335988605 2583741355 933716686 1644403538 1970423306 304500250 905101643 1814942168 1136358764 88729799 1577263...

output:

864191193907
3435484213046
1609855585257
794670034691
239792547603
1569523454006
592222190840
1348977639695
971907678206
571701308760
1222154327737
588622962923
2175170286205
1003932907552
3171825984588
3079336543944
2496162318055
1791043198440
868344685303
246730265657
2789305807883
1701594916685
1...

result:

wrong answer 1st lines differ - expected: '867006634793', found: '864191193907'

Subtask #2:

score: 0
Wrong Answer

Test #5:

score: 0
Wrong Answer
time: 383ms
memory: 295720kb

input:

500000 100000
12261386944926786495 7846697792998647383 16622924885320463714 170129022271213944 12625257523700625864 7684671687986103560 11532026873918423068 1131776055566669037 8263146651412710501 17872572061246021001 5017109039248728310 11088626167542318645 13810119722795416818 10928315716094262229...

output:

-6109605106711760776
-6852887562702776300
5653988472748567965
6281173414355612100
-419308296258819075
2903343914316621940
-9024282197402130985
76690753587353877
798850376670823348
-8309613438788409968
-4532312185474678257
-8254653402673898431
-6876998361742477219
-6143672567864504813
637460082558284...

result:

wrong answer 1st lines differ - expected: '12337138966997790840', found: '-6109605106711760776'

Subtask #3:

score: 0
Skipped

Dependency #2:

0%

Subtask #4:

score: 0
Time Limit Exceeded

Test #15:

score: 0
Time Limit Exceeded

input:

100000 100000
860905160 3192911636 290327446 2020707113 959258245 454185039 421895589 1070265496 2218913641 1684685660 1206723673 2606734467 4247254571 3341954386 3805299640 1702270353 2472053741 2816060613 1307901348 2702949728 879391505 884661815 330738731 1575749344 1239158446 2099693858 67466644...

output:


result:


Subtask #5:

score: 0
Skipped

Dependency #4:

0%

Subtask #6:

score: 0
Skipped

Dependency #1:

0%

Subtask #7:

score: 0
Skipped

Dependency #1:

0%