前言:
明天英语+线代,我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; }