1. 程式人生 > >Codeforces Round #553 (Div. 2) C. Problem for Nazar 數學

Codeforces Round #553 (Div. 2) C. Problem for Nazar 數學

pac 記得 sed ces lse 偶數 clas bsp 就是

題意:從奇數列 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

Codeforces Round #553 (Div. 2) C. Problem for Nazar 數學