D. Sum of XOR Functions
题解
1.暴力枚举每一个区间,然后加和 \(\to \ O(n^2)\)
如何优化?考虑到区间异或和不一定每一位都对答案有贡献,所以我们只考虑对答案有贡献的区间
2.遍历每一位,找出能使他对答案有贡献的区间个数,再乘上区间长度
细节
由于有求模运算,所以减法可能会出现负数,通过加一个模数解决
code
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=998244353;
ll a[300005];
ll sum[2]={0};
ll cnt[2]={0};
inline void read(ll &x) {
x = 0;
ll flag = 1;
char c = getchar();
while(c < '0' || c > '9'){
if(c == '-') flag = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
x = (x << 3) + (x << 1) + (c ^ 48);
c = getchar();
}
x *= flag;
}
inline void write(ll x)
{
if(x < 0){
putchar('-');
x = -x;
}
if(x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
int main()
{
ll n;
read(n);
for(ll i=1; i<=n; i++) read(a[i]);
ll ans=0;
for(ll k=0; k<=31; k++)
{
ll flag=0;
sum[0]=0;
sum[1]=0;
cnt[0]=1;
cnt[1]=0;
for(ll i=1; i<=n; i++)
{
flag^=((a[i]>>k)&1LL);
ans = (ans + (i * cnt[flag^1] % mod - sum[flag^1] + mod) % mod * (1LL << k) % mod) % mod;
sum[flag] = (sum[flag] + i) % mod;
cnt[flag] = (cnt[flag] + 1) % mod;
}
}
write(ans);
return 0;
}