首页 > Web开发 > 详细

http://codeforces.com/problemset/problem/768/B B. Code For 1

时间:2017-11-13 16:12:26      阅读:324      评论:0      收藏:0      [点我收藏+]
技术分享
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 long long bit[70];
 4 void init()
 5 {
 6     bit[1]=1;
 7     for(int i=2;i<=55;++i)
 8     {
 9         bit[i]=2*bit[i-1]+1;
10     }
11 }
12 long long getRes(long long n,long long  x)
13 {//数字n,第x位
14     if(x==0)return 0;
15     long long res=0;
16     long long bitsCnt=bit[lower_bound(bit+1,bit+55+1,n/2)-bit];
17     //printf("n=%I64d,x=%I64d,bitsCnt=%I64d\n",n,x,bitsCnt);
18     if(n==1)return 1;
19     if(x==bitsCnt+1)
20     {
21         if(n%2==1)res++;
22         res+=n/2;
23         return res;
24     }
25     else if(x>bitsCnt+1)
26     {
27         if(n%2==1)res++;
28         res+=n/2;
29         res+=getRes(n/2,x-bitsCnt-1);
30     }
31     else 
32     {
33         res+=getRes(n/2,x);
34     }
35     //printf("res=%I64d\n",res);
36     return res;
37 }
38 int main() {
39     long long n,l,r;
40     init();
41     scanf("%I64d%I64d%I64d",&n,&l,&r);
42     if(n==0)
43     {
44         printf("0\n");
45         return 0;
46     }
47     int index=lower_bound(bit+1,bit+55+1,n)-bit;
48     long long res1=getRes(n,l-1);
49     long long res2=getRes(n,r);
50     //printf("res1=%I64d,res2=%I64d\n",res1,res2);
51     printf("%I64d\n",res2-res1);
52     return 0;
53 }
View Code

 

题目:

Initially Sam has a list with a single element n. Then he has to perform certain operations on this list. In each operation Sam must remove any element x, such that x?>?1, from the list and insert at the same position 技术分享技术分享技术分享 sequentially. He must continue with these operations until all the elements in the list are either 0 or 1.

Now the masters want the total number of 1s in the range l to r (1-indexed). Sam wants to become a maester but unfortunately he cannot solve this problem. Can you help Sam to pass the eligibility test?

The first line contains three integers nlr (0?≤?n?<?250, 0?≤?r?-?l?≤?105, r?≥?1, l?≥?1) – initial element and the range lto r.

It is guaranteed that r is not greater than the length of the final list.

Output

Output the total number of 1s in the range l to r in the final sequence.

分析:

非常有趣的一道题,就是说我们有一个数n我们把它打散为一串0,1序列,方式如上所述,问l到r中有多少个1。

打散方式:比如说7,技术分享

先通过找规律我们可以发现以下两条结论:

1,数x打散后的序列中有x个1。

2,数x打散后的序列有 2n-1位数,其中2n-1为刚好大于等于x的数。

现在给你l,r,问从第l位到第r位有多少个1.

那么这个问题,我们就可以转化为第x位以前有多少个1,然后再相减,就是答案了。

我们可以采用线段树的思想,

 

技术分享

 

 这样我们就可以利用第2条确定向左走还是向右走,第1条来确定有多少个1了。

http://codeforces.com/problemset/problem/768/B B. Code For 1

原文:http://www.cnblogs.com/sun-yinkai/p/7826108.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!