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 }