Divide by Zero 2017 and Codeforces Round #399 (Div. 1 + Div. 2, combined) B. Code For 1

地址:http://codeforces.com/contest/768/problem/B

题目:

B. Code For 1
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Jon fought bravely to rescue the wildlings who were attacked by the white-walkers at Hardhome. On his arrival, Sam tells him that he wants to go to Oldtown to train at the Citadel to become a maester, so he can return and take the deceased Aemon's place as maester of Castle Black. Jon agrees to Sam's proposal and Sam sets off his journey to the Citadel. However becoming a trainee at the Citadel is not a cakewalk and hence the maesters at the Citadel gave Sam a problem to test his eligibility.

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?

Input

The first line contains three integers nlr (0 ≤ n < 250, 0 ≤ r - l ≤ 105, r ≥ 1, l ≥ 1) – initial element and the range l to 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.

Examples
input
7 2 5
output
4
input
10 3 10
output
5
Note

Consider first example:

Elements on positions from 2-nd to 5-th in list is [1, 1, 1, 1]. The number of ones is 4.

For the second example:

Elements on positions from 3-rd to 10-th in list is [1, 1, 1, 0, 1, 0, 1, 0]. The number of ones is 5.

 

思路:因为r-l<=1e5,所以可以求出l,r中每个数的值,然后求和。

  求值的时候,可以通过不断对称求出,就像一张纸可以不断对折。(画出那棵树你就能看出规律了)。

  O((r-l)logn)

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 #define MP make_pair
 6 #define PB push_back
 7 typedef long long LL;
 8 typedef pair<int,int> PII;
 9 const double eps=1e-8;
10 const double pi=acos(-1.0);
11 const int K=1e6+7;
12 const int mod=1e9+7;
13 
14 LL n,l,r,ans;
15 LL a[100],p[100],sum;
16 
17 int sc(LL x,int t)
18 {
19     while(p[t]!=x)
20     {
21         if(x>p[t])  x=p[t]*2-x;
22         t--;
23     }
24     return a[sum-t];
25 }
26 
27 int main(void)
28 {
29     p[0]=1;
30     cin>>n>>l>>r;
31     while(n>1)
32         a[sum++]=n%2,n/=2,p[sum]=p[sum-1]*2;
33     if(n!=0)
34         a[sum]=1;
35     for(LL i=l;i<=r;i++)
36         ans+=sc(i,sum);
37     cout<<ans<<endl;
38     return 0;
39 }
原文地址:https://www.cnblogs.com/weeping/p/6425881.html