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 }
View Code

 

posted @ 2018-07-01 09:27  zhangqingqi  阅读(184)  评论(0编辑  收藏  举报