2023牛客暑期多校训练营5-I The Yakumo Family

2023牛客暑期多校训练营5-I The Yakumo Family

https://ac.nowcoder.com/acm/contest/57359/I

文章目录

  • 2023牛客暑期多校训练营5-I The Yakumo Family
    • 题意
    • 解题思路
    • 代码

题意

2023牛客暑期多校训练营5-I The Yakumo Family_第1张图片

解题思路

考虑将序列拆位计算。

先考虑一个简化版本,求:
∑ 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) 1l1r1nXOR(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 bl1br在这一位上是否为 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) 1l1r1XOR(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_11l1r1nr1<l2r2nXOR(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} sl21,即 r 1 r_1 r1 [ 1 , l 2 − 1 ] [1,l_2-1] [1,l21]区间的总贡献。再求取一遍前缀和,可得答案。

k k k个不相交的区间,只需重复求取 k k k次,即可得答案。

代码

#include
#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]<

你可能感兴趣的:(多校联赛,算法,c++)