0%

2026天梯赛选拔赛-L3-1-辉夜的幻想世界

题目大意

题目总结:

给定一个长度为 n 的数组 a

对任意区间 [l, r],定义其权值为:

w=i=lrj=lr(aiaj) w=\sum_{i=l}^{r}\sum_{j=l}^{r}(a_i \oplus a_j)

其中 表示按位异或。

要求你计算数组中所有非空子区间的权值之和,并对 10^9+7 取模后输出。

输入范围为:

  • 1 ≤ n ≤ 2×10^5

  • 0 ≤ a_i ≤ 10^6

输出一个整数,表示最终答案。

样例:

1
2
3
4
5
6
输入:
6
1 1 4 5 1 4

输出:
422

样例含义:对数组 [1,1,4,5,1,4] 的所有非空子区间分别计算上述双重异或和权值,再把这些权值全部累加,最终结果为 422

思路讲解

注意,题目中的是非有序对双重求和,所以结果不要忘记乘以一个 2。

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
vector<vector<ll>> suf_bits(N+2,vector<ll>(26));
vector<vector<ll>> suf_nobits(N+2,vector<ll>(26));
for (ll i=N;i>=1;--i) {
for (int j=0;j<25;++j) {
// 注意,我们这里写的是(N-i+1),是指的包含 i 的可以选择的右端点数量
suf_bits[i][j]=suf_bits[i+1][j]+(A[i]>>j&1)*(N-i+1);
// (A[i]>>j&1)^1,不要偷懒,不加这个 &1,一定要有 &1 才对
suf_nobits[i][j]=suf_nobits[i+1][j]+((A[i]>>j&1)^1)*(N-i+1);
}
}
ll ans=0;
for (int i=1;i<=N;++i) {
for (int j=0;j<25;++j) {
if (A[i]>>j&1) {
ll suf=suf_nobits[i+1][j];
ll lans=suf%mod*i%mod;
lans*=(1ll<<j);
lans%=mod;
ans+=lans*2;
ans%=mod;
}else {
ll suf=suf_bits[i+1][j];
ll lans=suf%mod*i%mod;
lans*=(1ll<<j);
lans%=mod;
ans+=lans*2;
ans%=mod;
}
}
}

AC代码

AC
http://10.199.227.101/contest/1005/problem/L3-1/submission-detail/2157

心路历程(WA,TLE,MLE……)