题目描述 https://www.luogu.com.cn/problem/P3760
简要题意:给定一个长度为 $n$ 的序列 $a_i$,求所有区间和的异或和
$n\le 10^5,\sum a_i\le 10^6$
Solution 我们要求这个东西 $\bigoplus_{1\le j\le i\le n}s_i-s_{j-1}$
考虑这样一个做法,我们枚举右端点,维护左端点的异或值
那么每次相当于全局加 $1$,求全局异或和,这个东西可以拿 $01Trie$ 来做
时间复杂度为 $O((n+\sum a_i)\log \sum a_i)$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 #include <iostream> #include <cstdio> #define maxn 100010 #define Maxn 1000010 using namespace std ;int n, a[maxn], s[maxn];#define lc T[i].ch[0] #define rc T[i].ch[1] const int N = 20 ;struct Trie { int v, sum, ch[2 ]; } T[Maxn * 21 ]; int rt = 1 , top = 1 ; inline void maintain (int i) { T[i].v = T[lc].v + T[rc].v; T[i].sum = T[lc].sum << 1 ; T[i].sum ^= T[rc].sum << 1 | T[rc].v & 1 ; } void ins (int &i, int v, int o) { if (!i) i = ++top; if (o == N + 1 ) return (void ) (++T[i].v); int d = v >> o & 1 ; ins(T[i].ch[d], v, o + 1 ); maintain(i); } void add (int i) { if (!i) return ; add(rc); swap(lc, rc); maintain(i); } int ans;int main () { ios::sync_with_stdio(false ); cin .tie(nullptr ); cout .tie(nullptr ); cin >> n; for (int i = 1 ; i <= n; ++i) cin >> a[i]; for (int i = 0 ; i <= n; ++i) { for (int j = 1 ; j <= a[i]; ++j) add(rt); ins(rt, 0 , 0 ); ans ^= T[rt].sum; } cout << ans << "\n" ; return 0 ; }