Monday, January 14, 2019

[UVA] 12866 - Combination

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : 12866 - Combination
Source            : UVA Online Judge
Category          : Number Theory, Dynamic Programing
Algorithm         : Lukas Theorem, Digit DP
Verdict           : Accepted

  1. #include "bits/stdc++.h"  
  2.   
  3. using namespace std;  
  4.   
  5. #define ll         unsigned long long int   
  6.   
  7. ll dp[70][70];  
  8. bool memoize[70][70];  
  9. int a[70];  
  10.   
  11. inline ll solve(int pos, int one = 0, bool flag = 1, bool take = 0)  
  12. {  
  13.       if (pos < 0) return (1LL << one);  
  14.       ll &ret = dp[pos][one];  
  15.       bool &mem = memoize[pos][one];  
  16.       if (!flag && take && mem) return ret;  
  17.       ll sum = 0;  
  18.       int loop = 1;  
  19.       if (flag) loop = a[pos];  
  20.       for (int i = 0; i <= loop; i++)  
  21.       {  
  22.             if (!take && i == 0) sum += solve(pos-1, 0, 0, 0);  
  23.             else sum += solve(pos-1, one + (i == 1), flag & i == a[pos], 1);  
  24.       }  
  25.       if (!flag && take) mem = 1, ret = sum;  
  26.       return sum;  
  27. }  
  28.   
  29. inline ll digitDP(ll n)  
  30. {  
  31.       if (n < 0) return 0;  
  32.       int len = 0;  
  33.       while (n)  
  34.       {  
  35.             a[len++] = n % 2;  
  36.             n /= 2;  
  37.       }  
  38.       return solve(len-1);  
  39. }  
  40.   
  41. int main()  
  42. {  
  43.       ll a, b;  
  44.       while (scanf("%llu %llu", &a, &b) == 2)  
  45.       {  
  46.             if (a == 0 && b == 0) break;  
  47.             ll sum = digitDP(b);  
  48.             if (a > 0) sum -= digitDP(a-1);  
  49.             printf("%llu\n", sum);  
  50.       }  
  51. }  

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.