Problem: Uva 12208 - How Many Ones Needed?
Read:
[1] Recurrence Relation : How many 1's between 0 to (2^n-1)
[2] Recurrence Relation : How many 1's between 0 to n
Concept:
Total Number of 1's bit between n to m = Total Number of 1's bit between 0 to m - Total Number of 1's bit between 0 to n-1
Pre Calculation:
(20002000000000 = 1110111001101011001010000000000
only 32 bits needed... n = 32
o[n] (described above)
v[n] = 2^n - 1
1st step:Total Number of 1 bit between 0 to n-1
1. Let, N:= n-1; To1:=0
2. tm:= N;
3. find i, where v[i]>tm
4. To1 = o[i-1]
5. MSB_ONE = tm - v[i-1];
6. To1 = To1+MSB_ONE;
7. Now new N = MSB_ONE-1;
8. break if N<=0; otherwise go to step 2
Find To1 Finally.
2nd Step: Total Number of 1 bit between 0 to m
Find To2 according to above algorithm
3rd step: Total 1's
Print To2 - To1;
Read:
[1] Recurrence Relation : How many 1's between 0 to (2^n-1)
[2] Recurrence Relation : How many 1's between 0 to n
Concept:
Total Number of 1's bit between n to m = Total Number of 1's bit between 0 to m - Total Number of 1's bit between 0 to n-1
Pre Calculation:
(20002000000000 = 1110111001101011001010000000000
only 32 bits needed... n = 32
o[n] (described above)
v[n] = 2^n - 1
1st step:Total Number of 1 bit between 0 to n-1
1. Let, N:= n-1; To1:=0
2. tm:= N;
3. find i, where v[i]>tm
4. To1 = o[i-1]
5. MSB_ONE = tm - v[i-1];
6. To1 = To1+MSB_ONE;
7. Now new N = MSB_ONE-1;
8. break if N<=0; otherwise go to step 2
Find To1 Finally.
2nd Step: Total Number of 1 bit between 0 to m
Find To2 according to above algorithm
3rd step: Total 1's
Print To2 - To1;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | #include<stdio.h> typedef long long LL; int main(){ LL o[32],v[32],two,n,m,To1,To2,msb_one,tm,C; int i; /*freopen("b.in","r",stdin);*/ o[1]=1; v[1]=1; two = 1; for (i=2;i<32;i++){ two = two<<1; v[i] =(two<<1)-1; o[i] = two + 2*o[i-1]; } C = 0; while(1){ scanf("%lld %lld",&n,&m); if (n==0 && m==0) break; To1 = 0; tm = n-1; while(tm>0){ for(i=1;;i++){ if(v[i]>tm) break; } i = i-1; To1=To1+o[i]; msb_one=(tm-v[i]); To1=To1+msb_one; tm=msb_one-1; } To2 = 0; tm = m; while(tm>0){ for(i=1;;i++){ if(v[i]>tm) break; } i = i-1; To2=To2+o[i]; msb_one=(tm-v[i]); To2=To2+msb_one; tm=msb_one-1; } printf("Case %lld: %lld\n",++C,To2-To1); } return 0; } |
No comments:
Post a Comment