题意:求子区间异或和,要求区间长度在l到r之间,并且为偶数
题解:对于每一位算贡献,可以分奇偶来记录,计算的时候只加上奇偶性相同的就保证了为偶数,从大于l的点开始每次++,从大于r的点每次--,记录二进制上所有权值和
代码:
1 #include<bits/stdc++.h> 2 #define db double 3 #define ll long long 4 #define vec vector<ll> 5 #define Mt vector<vec> 6 #define ci(x) scanf("%d",&x) 7 #define cd(x) scanf("%lf",&x) 8 #define cl(x) scanf("%lld",&x) 9 #define pi(x) printf("%d\n",x) 10 #define pd(x) printf("%f\n",x) 11 #define pl(x) printf("%lld\n",x) 12 #define rep(i,x,y) for(int i=x;i<=y;i++) 13 #define debug puts("-------------"); 14 const int N = 1e6 + 5; 15 const int mod = 1e9 + 7; 16 const int MOD = mod-1; 17 const db eps = 1e-18; 18 const db PI = acos(-1.0); 19 using namespace std; 20 ll a[N]; 21 ll d[2][2]; 22 int main() 23 { 24 int n,l,r; 25 ci(n),ci(l),ci(r); 26 for(int i=1;i<=n;i++)cin>>a[i],a[i]^=a[i-1]; 27 ll ss=0; 28 if(l&1) l++; 29 if(r&1) r--; 30 if(l>r) return 0*puts("0"); 31 for(int i=0;i<31;i++) 32 { 33 ll ans=0; 34 memset(d,0, sizeof(d)); 35 for(int j=1;j<=n;j++) 36 { 37 if(j>=l) d[(j-l)&1][(a[j-l]>>i)&1]++,ans=(ans+d[j&1][!((a[j]>>i)&1)])%mod; 38 if(j>=r) d[(j-r)&1][(a[j-r]>>i)&1]--; 39 } 40 ss=(ss+ans*(1ll<<i)%mod)%mod; 41 } 42 pl((ss+mod)%mod); 43 return 0; 44 }
时间: 2024-11-07 00:04:32