Sum of XOR Functions

Sum of XOR Functions

题目

有一个序列 a,计算:

l=1nr=ln(rl+1)×i=lrai

思路

位运算的题,我们对于每一位进行考虑,会发现构成了很多个 0,1 序列,则我们对于每一个序列考虑价值,求和即可。

b 序列为这一位上的 0,1 序列。

对于 0,1 序列的一段区间的异或和,只有在这段区间中 1 的数量为奇数个时才为 1

我们用 cnti,0/1 表示这一位的零一序列中第 i 个位置前 0/1 出现的个数。

sumi,0/1 表示:

{k=xibk}=0/1x(ix)

也就是说,表示对于 i 位置前所有能满足使 {k=xibk}=1 的位置 x 到位置 i 的距离和。

我们发现当我们预处理完成这些数组时,就可以 O(1) 求出:x=1i{k=xibk} 的值了。

接下来就是 O(n) 的复杂度枚举右端点的值即可。

主要思路到此结束。

code

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
#define int long long
const int MOD = 998244353;
const int MAXN = 3e5 + 7;
int n,a[MAXN];
int cnt[MAXN][2],sum[MAXN][2];
int pre[MAXN];
int ans = 0;
signed main(){
	scanf("%lld", &n);
	for(int i = 1;i <= n;i++) scanf("%lld", &a[i]);
	for(int w = 0;w <= 31;w++){
		memset(cnt,0,sizeof(cnt));
		memset(sum,0,sizeof(sum));
		memset(pre,0,sizeof(pre));
		cnt[0][0] = 1;
		for(int i = 1;i <= n;i++){
			pre[i] = pre[i - 1];
			cnt[i][0] = cnt[i - 1][0];
			cnt[i][1] = cnt[i - 1][1];
			sum[i][0] = sum[i - 1][0];
			sum[i][1] = sum[i - 1][1];
			pre[i] += (a[i] >> w) & 1;
			if(pre[i] & 1) cnt[i][1]++,sum[i][1] += i;
			else cnt[i][0]++,sum[i][0] += i;
		}
		for(int i = 1;i <= n;i++){
			if(pre[i] & 1) ans = (ans + ((cnt[i - 1][0] * i - sum[i - 1][0]) % MOD) * (1 << w) % MOD) % MOD;
			else ans = (ans + ((cnt[i - 1][1] * i - sum[i - 1][1]) % MOD) * (1 << w) % MOD) % MOD;
			ans = ans % MOD;
		}
	}
	cout<<ans;
	return 0;
}
posted @   wyl123ly  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示