cf 399 div.1 B
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 }