1. 程式人生 > >cf 399 div.1 B

cf 399 div.1 B

lse type 順序 hid clu 對數 cst tdi 分享圖片

CF 768B 有一個序列,剛開始,只有1個數n,接著按照以下順序變化:找 到序列中任意一個> 1的數p,將他變為p 2 , p mod 2, p 2 直到所有 點數都不大於1為止。問最後的序列l ? r中有多少個1 r-l<=1e6,n,l,r <= 250 模擬 + 分治。像二叉搜索樹一樣遞歸 O(nlogn) longlong 取對數要用 longdouble 技術分享圖片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5
#include<cmath> 6 using namespace std; 7 8 typedef long long ll; 9 ll n,l,r,power[60]; 10 int ans; 11 12 inline int log_(ll x){ 13 return (int)floor(log((long double)x) / log(2)); 14 } 15 /*inline ll power(ll x,int y){ 16 ll res = 1; 17 while ( y ){ 18 if ( y & 1 ) res *= x;
19 y >>= 1; 20 x *= x; 21 } 22 return res; 23 }*/ 24 void solve(ll n,ll l,ll r){ 25 if ( l > r ) return; 26 if ( n < 2 ){ ans += (int)n; return; } 27 ll lsum = power[log_(n / 2) + 1] - 1; 28 // cout<<n<<" "<<l<<" "<<r<<" "<<lsum<<endl;
29 if ( l <= lsum && r <= lsum ) solve(n / 2,l,r); 30 else if ( l <= lsum && r > lsum ) solve(n / 2,l,lsum) , solve(n / 2,1,r - lsum - 1) , ans += (int)n % 2; 31 else if ( l > lsum ){ 32 if ( l == lsum + 1 ) ans += (int)n % 2 , solve(n / 2,1,r - lsum - 1); 33 else solve(n / 2,l - lsum - 1,r - lsum - 1); 34 } 35 } 36 int main(){ 37 //freopen("output.txt","w",stdout); 38 power[0] = 1; 39 for (int i = 1 ; i <= 60 ; i++) power[i] = power[i - 1] * 2ll; 40 cin>>n>>l>>r; 41 solve(n,l,r); 42 cout<<ans<<endl; 43 return 0; 44 }
View Code

cf 399 div.1 B