D. Sum of XOR Functions

发布时间 2023-10-09 14:58:51作者: onlyblues

D. Sum of XOR Functions

You are given an array $a$ of length $n$ consisting of non-negative integers.

You have to calculate the value of $\sum_{l=1}^{n} \sum_{r=l}^{n} f(l, r) \cdot (r - l + 1)$, where $f(l, r)$ is $a_l \oplus a_{l+1} \oplus \dots \oplus a_{r-1} \oplus a_r$ (the character $\oplus$ denotes bitwise XOR).

Since the answer can be very large, print it modulo $998244353$.

Input

The first line contains one integer $n$ ($1 \le n \le 3 \cdot 10^5$) — the length of the array $a$.

The second line contains $n$ integers $a_1, a_2, \dots, a_n$ ($0 \le a_i \le 10^9)$.

Output

Print the one integer — the value of $\sum_{l=1}^{n} \sum_{r=l}^{n} f(l, r) \cdot (r - l + 1)$, taken modulo $998244353$.

Examples

Input

3
1 3 2

Output

12

Input

4
39 68 31 80

Output

1337

Input

7
313539461 779847196 221612534 488613315 633203958 394620685 761188160

Output

257421502

Note

In the first example, the answer is equal to $f(1, 1) + 2 \cdot f(1, 2) + 3 \cdot f(1, 3) + f(2, 2) + 2 \cdot f(2, 3) + f(3, 3) = $ $= 1 + 2 \cdot 2 + 3 \cdot 0 + 3 + 2 \cdot 1 + 2 = 12$.

 

解题思路

  如果涉及到位运算的话一般都是按位来考虑,并且每一位的计算是相互独立的。对于 $f(l,r) \cdot (r-l+1)$,我们把 $f(l,r)$ 看成是二进制转十进制的形式,例如有 $26 = (11010)_2 = 2^4 + 2^3 + 2^1$。由于 $a_i$ 的最大取值是 ${10}^9$,因此在二进制下最多有 $30$ 位,在按位的考虑的思想下,$\sum\limits_{l=1}^{n} \sum\limits_{r=l}^{n} f(l, r) \cdot (r - l + 1)$ 的结果可以看成是 $2^0 \cdot x_0 + 2^1 \cdot x_1 + \cdots + 2^{29} \cdot x_{29}$ 的形式,其中 $x_k$ 表示考虑每个 $a_i$ 的第 $k$ 位时 $\sum\limits_{l=1}^{n} \sum\limits_{r=l}^{n} f_k(l, r) \cdot (r - l + 1)$ 的结果,有 $f_k(l,r) = a_{l,k} \oplus a_{l+1,k} \oplus \dots \oplus a_{r-1,k} \oplus a_{r,k}$,$a_{l,k}$ 表示 $a_{l}$ 在二进制下第 $k$ 位的数值。

  当我们考虑按位计算是,本质上是处理由 $a_{1,k}, a_{2,k}, \ldots, a_{n,k}$ 构成的 $01$ 串,因此 $f_k(l,r)$ 的值不是 $0$ 就是 $1$,而只有当 $f_k(l,r) = 1$ 时才有意义。为此我们应该统计所有 $f_k(l,r) = 1$ 的连续子串的长度总和。我们按右端点来对所有连续子串进行分类,当其右端点 $r$ 固定后,我们要找到所有满足 $f_k(l,r) = 1$ 的 $l$,其中 $l \in [1,r]$。为了方便这里定义前缀异或和 $s_i = a_{1,k} \oplus a_{2,k} \oplus \cdots \oplus a_{i,k}$,因此就等价于找到所有满足 $s_r \oplus s_l = 1, \, l \in [0,r-1]$ 的 $l$,然后再累加这些 $l$ 到 $r$ 的长度,也就是子串的长度。为此可以开个两个哈希表 $c_{0/1}$ 和 $g_{0/1}$,分别维护 $[0,r-1]$ 中 $s_i = 0/1$ 的下标数量,以及对应的下标的和。因此当 $r$ 固定后,满足 $f_k(l,r)=1$ 的子串长度总和就是 $r \cdot c_{s_r \oplus 1} - g_{s_r \oplus 1}$,对总的答案的贡献就是 $2^k \cdot (r \cdot c_{s_r \oplus 1} - g_{s_r \oplus 1})$。

   AC 代码如下,时间复杂度为 $O(n \log{A})$:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 
 6 const int N = 3e5 + 10, mod = 998244353;
 7 
 8 int a[N];
 9 
10 int main() {
11     int n;
12     scanf("%d", &n);
13     for (int i = 1; i <= n; i++) {
14         scanf("%d", a + i);
15     }
16     int ret = 0;
17     for (int k = 0; k <= 29; k++) {
18         int sum = 0, c[2] = {0}, s[2] = {0};
19         for (int i = 1; i <= n; i++) {
20             c[sum]++, s[sum] = (s[sum] + i - 1) % mod;
21             int x = a[i] >> k & 1;
22             sum ^= x;
23             ret = (ret + (1ll * c[sum ^ 1] * i % mod - s[sum ^ 1] + mod) % mod * (1 << k)) % mod;
24         }
25     }
26     printf("%d\n", ret);
27     
28     return 0;
29 }

 

参考资料

  Educational Codeforces Round 155 — Editorial:https://codeforces.com/blog/entry/120773