2023牛客暑期多校训练营5-I The Yakumo Family
https://ac.nowcoder.com/acm/contest/57359/I
文章目录
- 2023牛客暑期多校训练营5-I The Yakumo Family
- 题意
- 解题思路
- 代码
题意
解题思路
考虑将序列拆位计算。
先考虑一个简化版本,求:
∑
1
≤
l
1
≤
r
1
≤
n
X
O
R
(
l
1
,
r
1
)
\sum_{1\le l_1\le r_1\le n}XOR(l_1,r_1)
1≤l1≤r1≤n∑XOR(l1,r1)
先对序列 a a a取前缀异或 b b b,对于固定的点 r r r,一个区间 X O R ( l , r ) XOR(l_,r) XOR(l,r),其某一位是否有贡献取决于 b l − 1 ⊕ b r b_{l-1}\oplus b_r bl−1⊕br在这一位上是否为 1 1 1,若是,则这一位的贡献加一。对于每一位,我们可以根据 r 1 r_1 r1的后移,统计 1 / 0 1/0 1/0的个数, O ( 1 ) O(1) O(1)计算这一位 ∑ 1 ≤ l 1 ≤ r 1 X O R ( l 1 , r 1 ) \sum _{1\le l_1\le r_1}XOR(l_1,r_1) ∑1≤l1≤r1XOR(l1,r1),设为 p r 1 p_{r_1} pr1。最后求取前缀和,得 s n s_n sn即为答案。
对于如下问题:
∑
1
≤
l
1
≤
r
1
≤
n
∑
r
1
<
l
2
≤
r
2
≤
n
X
O
R
(
l
1
,
r
1
)
×
X
O
R
(
l
2
,
r
2
)
\sum_{1\le l_1\le r_1\le n}\sum_{r_1<l_2\le r_2\le n}XOR(l_1,r_1)\times XOR(l_2,r_2)
1≤l1≤r1≤n∑r1<l2≤r2≤n∑XOR(l1,r1)×XOR(l2,r2)
对于每个固定的
r
2
r_2
r2,一个区间
[
l
2
,
r
2
]
[l_2,r_2]
[l2,r2]的贡献同样可由上述方法求得,不同的是其对每一位的贡献为之前求得的
s
l
2
−
1
s_{l_{2}-1}
sl2−1,即
r
1
r_1
r1在
[
1
,
l
2
−
1
]
[1,l_2-1]
[1,l2−1]区间的总贡献。再求取一遍前缀和,可得答案。
对 k k k个不相交的区间,只需重复求取 k k k次,即可得答案。
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+5,mod=998244353;
ll n,f[N],s[N],a[N];
ll t[N];
int main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>f[i],t[i]=1,s[i]=s[i-1]^f[i];
t[0]=1;
for(int w=1;w<=3;w++){
for(int j=0;j<=30;++j){
ll p[2];
p[0]=t[0],p[1]=0;
for(int i=1;i<=n;++i){
int g=(s[i]>>j)&1;
a[i]=(a[i]+(p[g^1]<<j)%mod)%mod;
p[g]+=t[i];
p[g]%=mod;
}
}
t[0]=0;
for(int i=1;i<=n;i++)t[i]=(t[i-1]+a[i])%mod,a[i]=0;
}
cout<<t[n];
}