前言:
明天英语+线代,我0基础上去能过吗?显然是可以的(希望明天运气好!!!)
思路:
会按位运算这题就能过,但是我连位运算怎么前缀和都给忘了...菜的离谱,偷瞄了一下别人的博客emmm秒懂了.
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+500,M=32;
const int mod=1e9+7;
int sum[N][M];//到了第i位,数位为j,的1的个数和.
int w[N];
int main()
{
int n,l,r,x;ll ans=0;
scanf("%d%d%d",&n,&l,&r);
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
w[i]^=w[i-1];w[i]^=x;
for(int j=0;j<=30;j++)
{
if(i!=1) sum[i][j]+=sum[i-2][j];
if(w[i]>>j&1) sum[i][j]++;
}
}
for(int i=0;i<=n;i++)
{
int L=i+l;int R=min((i+r),n);
if(((i&1)^(L&1))) L++;
if(((i&1)^(R&1))) R--;
if(L>n) break;
if(L>R) continue;
for(int j=0;j<=30;j++)
{
int tot=(R-L)/2+1;//总共数量.
int res=sum[R][j]-sum[max(0,L-2)][j];//1的数量
if(w[i]>>j&1)
{
ans+=(tot-res)*(1ll<<j);
ans%=mod;
}
else
{
ans+=res*(1ll<<j);
ans%mod;
}
}
}printf("%lld\n",ans);
return 0;
}
京公网安备 11010502036488号