Codeforces Round #553 (Div. 2) C. Problem for Nazar 数学

题意:从奇数列 1 3 5 7 9 ....  偶数列2 4 6 8 10...分别轮流取 1 2 4 ....2^n 个数构成新数列 求新数列的区间和 (就一次询问)

思路:首先单次区间和就是一个简单的类似前缀和就可以搞定  那么如何求新数列的和呢

  我们明确一个观点:原数列的区间和结果显而易见  那么题目就转化成  奇数列和偶数列分别取了多少个数

  因为取数的数字的以2的幂递增的,所以 l r(<=1e18)  log2(1e18)很简单过

  而有了数量结果可以用0(1)的时间算出来

  记得瞎MOD 和LL

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int mod=1e9+7;
 5 ll solve(ll x){
 6     int flag=0;
 7     ll sum=0;
 8     ll sumodd=0,sumeven=0;
 9     ll i;
10     if(x<=0)return 0;
11     for(i=1;;i<<=1){
12         sum+=i;
13         if(sum>x){
14             sum-=i;
15             if(flag==0)sumodd+=(x-sum);
16             else sumeven+=(x-sum);
17             break;
18         }
19         if(flag==0)sumodd+=i;
20         else sumeven+=i;
21         flag^=1;
22     }
23     return ( (sumodd%mod)*(sumodd%mod)+(sumeven+1)%mod*(sumeven%mod))%mod;
24 
25 }
26 int main(){
27     ll l,r;
28 cin>>l>>r;
29 cout<<(solve(r)-solve(l-1)+mod)%mod<<endl;
30 
31     return 0;
32 }
View Code
原文地址:https://www.cnblogs.com/ttttttttrx/p/10793067.html