codeforce round 553div2C——前缀和

题目描述:给你一个按2的倍数奇偶交替的序列,问你从l到r相加之和为多少

比较容易想到可以计算出[1,l-1]的和与[1,r]的和这样的前缀和操作,又因为是2的幂这样累加的,所以我们可以直接统计[1,x]区间内奇数和偶数的个数,直接用等差数列求和即可。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

typedef long long ll;
const int mod=1e9+7;
//维护前缀和,直接计算1~x中有多少个奇数,多少个偶数就可以
ll get_sum(ll x){
    ll sum=0;
    int flag=0;
    ll sumodd=0,sumeven=0;
    if(x<=0)return 0;
    for(ll i=1;;i=i<<1){
        sum+=i;
        if(sum>x){
            sum-=i;
            if(!flag){
                sumodd+=x-sum;
            }
            else{
                sumeven+=x-sum;
            }
            break;
        }
        if(flag){
            sumeven+=i;
        }
        else{
            sumodd+=i;
        }
        flag^=1;
    }
    return ((sumodd%mod)*(sumodd%mod)+(sumeven+1)%mod*(sumeven%mod))%mod;
}
int main(){
    ll l,r;
    scanf("%lld%lld",&l,&r);
    ll ans=(get_sum(r)+mod-get_sum(l-1))%mod;
    printf("%lld\n",ans);
    return 0;
}

 

你可能感兴趣的:(思维题)