Saturday, April 13, 2019

[Toph] Easy Peasy Subset Sum

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : Easy Peasy Subset Sum
Source            : Toph
Category          : Data Structures
Algorithm         : Implicit Treap
Verdict           : Accepted

#include "bits/stdc++.h"
 
using namespace std;
 
#define ll              long long int
 
static const int maxn = 1e5 + 5;
static const ll mod = 1e9 + 7;
 
struct Node
{
      ll val, sum;
      int priority, sze;
      Node *lft, *rgt;
      Node(ll val = 0)
      {
            this->val = val;
            this->sum = val;
            this->priority = rand();
            this->sze = 1;
            this->lft = this->rgt = nullptr;
      }
};
 
typedef Node*             pnode;
 
int sz(pnode t)
{
      return (t == nullptr ? 0 : t->sze);
}
 
void updateSize(pnode t)
{
      if (t) t->sze = sz(t->lft) + 1 + sz(t->rgt);
}
 
void combine(pnode t)
{
      t->sum = t->val;
      if (t->lft) t->sum = (t->sum + t->lft->sum) % mod;
      if (t->rgt) t->sum = (t->sum + t->rgt->sum) % mod;
}
 
void Split(pnode t, pnode &l, pnode &r, int pos, int add = 0)
{
      // 'pos' goes to left subtree
      if (t == nullptr) return void(l = r = nullptr);
      int curr = sz(t->lft) + add;
      if (curr <= pos) Split(t->rgt, t->rgt, r, pos, curr + 1), l = t;
      else Split(t->lft, l, t->lft, pos, add), r = t;
      updateSize(t);
      combine(t);
}
 
void Merge(pnode &t, pnode l, pnode r)
{
      if (l == nullptr or r == nullptr) t = l ? l : r;
      else if (l->priority < r->priority) Merge(r->lft, l, r->lft), t = r;
      else Merge(l->rgt, l->rgt, r), t = l;
      updateSize(t);
      combine(t);
}
 
pnode Insert(pnode t, pnode newnode, int pos)
{
      pnode L, R;
      Split(t, L, R, pos - 1);
      Merge(t, L, newnode);
      Merge(t, t, R);
      return t;
}
 
ll query(pnode t, int pos)
{
      if (t == nullptr || pos <= 0) return 0;
      pnode L, R;
      Split(t, L, R, pos-1);
      ll sum = L->sum;
      Merge(t, L, R);
      return sum;
}
 
ll kth(pnode t, int k)
{
      if (t == nullptr) return -1;
      int curr = sz(t->lft) + 1;
      if (curr == k) return t->val;
      if (curr < k) return kth(t->rgt, k - curr);
      else return kth(t->lft, k);
}
 
int binarySearch(pnode t, ll val)
{
      int lo = 1;
      int hi = sz(t);
      int ans = 0;
      while (lo <= hi)
      {
            int mid = lo + hi >> 1;
            ll k = kth(t, mid);
            if (k <= val) ans = mid, lo = mid + 1;
            else hi = mid - 1;
      }
      return ans;
}
 
void display(pnode t)
{
      if (t == nullptr) return;
      display(t->lft);
      cerr << t->val << ' ';
      display(t->rgt);
}
 
ll power_two[maxn];
 
void power_calc()
{
      power_two[0] = 1;
      for (int i = 1; i < maxn; i++)
      {
            power_two[i] = (1LL * 2 * power_two[i-1]) % mod;
      }
}
 
int main()
{
      #ifndef ONLINE_JUDGE
            freopen("in.txt", "r", stdin);
      #endif // ONLINE_JUDGE
 
      power_calc();
 
      int n;
      cin >> n;
      vector <ll> arr(n);
      for (ll &x : arr) cin >> x;
 
      if (n == 1)
      {
            cout << 0 << '\n';
            exit(0);
      }
 
      pnode treap = nullptr;
      ll cumsum = 0;
      ll sum = 0;
      ll mul = power_two[n-2];
 
      for (int i = n-1; i >= 0; i--)
      {
            ll x = arr[i];
 
            ll small_or_equal = binarySearch(treap, x);
            ll greatter = sz(treap) - small_or_equal;
 
            ll small_or_equal_sum = query(treap, small_or_equal);
            ll greatter_sum = cumsum - small_or_equal_sum;
 
            //cerr << i << " -> " << small_or_equal << " : " << greatter << endl;
            //cerr << small_or_equal_sum << " -- " << greatter_sum << endl;
 
 
            ll p = (small_or_equal * mul % mod * x) % mod;
            ll q = (mul * small_or_equal_sum) % mod;
 
            ll add_small_or_equal = (p - q + mod) % mod;
 
            p = (mul * greatter_sum) % mod;
            q = (mul * x % mod * greatter) % mod;
 
            ll add_greatter = (p - q + mod) % mod;
 
            sum = (sum + add_small_or_equal + add_greatter) % mod;
 
            cumsum = (cumsum + x) % mod;
            x %= mod;
            treap = Insert(treap, new Node(x), small_or_equal);
      }
      cout << sum << '\n';
      //display(treap);
}
 

Monday, April 8, 2019

[Codeforces] C. k-Tree

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : C. k-Tree
Source            : Codeforces
Category          : Dynamic Programing
Algorithm         : Basic Dynamic Programing
Verdict           : Accepted

  1. #include <bits/stdc++.h>  
  2.   
  3. using namespace std;  
  4.   
  5. static const int maxn = 100 + 5;  
  6. static const int mod = (int)1e9+7;  
  7.   
  8. int add(int a, int b)  
  9. {  
  10.       a += b;  
  11.       if (a >= mod) a -= mod;  
  12.       return a;  
  13. }  
  14.   
  15. int dp[maxn][2];  
  16. bool memoize[maxn][2];  
  17. int n, k, d;  
  18.   
  19. int solve(int sum = 0, bool flag = 0)  
  20. {  
  21.       if (sum == n) return flag;  
  22.       if (sum > n) return 0;  
  23.       int &ret = dp[sum][flag];  
  24.       bool &mem = memoize[sum][flag];  
  25.       if (mem) return ret;  
  26.       mem = 1;  
  27.       ret = 0;  
  28.       for (int weight = 1; weight <= k; weight++)  
  29.       {  
  30.             ret = add(ret, solve(sum + weight, flag | weight >= d));  
  31.       }  
  32.       return ret;  
  33. }  
  34.   
  35. int main()  
  36. {  
  37.       ios_base::sync_with_stdio(false);  
  38.       cin.tie(NULL);  
  39.       cout << fixed << setprecision(15);  
  40.       #ifndef ONLINE_JUDGE  
  41.             freopen("in.txt""r", stdin);  
  42.       #endif // ONLINE_JUDGE  
  43.   
  44.       cin >> n >> k >> d;  
  45.       cout << solve(0, 0) << '\n';  
  46. }  

[Codeforces] D. Random Task

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : D. Random Task
Source            : Codeforces
Category          : Dynamic Programing, Search
Algorithm         : Digit DP, Binary Search
Verdict           : Accepted

  1. #include <bits/stdc++.h>  
  2.   
  3. using namespace std;  
  4.   
  5. #define ll            long long int  
  6.   
  7. ll dp[70][70];  
  8. bool memoize[70][70];  
  9. int a[70];  
  10.   
  11. ll m, k;  
  12.   
  13. ll solve(int pos, int one = 0, bool flag = 1, bool take = 0)  
  14. {  
  15.       if (pos < 0) return one == k;  
  16.       ll &ret = dp[pos][one];  
  17.       bool &mem = memoize[pos][one];  
  18.       if (!flag && take && mem) return ret;  
  19.       int loop = 1;  
  20.       if (flag) loop = a[pos];  
  21.       ll sum = 0;  
  22.       for (int i = 0; i <= loop; i++)  
  23.       {  
  24.             if (!take && i == 0) sum += solve(pos-1, 0, 0, 0);  
  25.             else sum += solve(pos-1, one + i, flag & i == a[pos], 1);  
  26.       }  
  27.       if (!flag && take) mem = 1, ret = sum;  
  28.       return sum;  
  29. }  
  30.   
  31. ll digit_dp(ll num)  
  32. {  
  33.       int len = 0;  
  34.       while (num) a[len++] = num % 2, num /= 2;  
  35.       return solve(len-1);  
  36. }  
  37.   
  38. int main()  
  39. {  
  40.       ios_base::sync_with_stdio(false);  
  41.       cin.tie(NULL);  
  42.       cout << fixed << setprecision(15);  
  43.       #ifndef ONLINE_JUDGE  
  44.             freopen("in.txt""r", stdin);  
  45.       #endif // ONLINE_JUDGE  
  46.   
  47.       cin >> m >> k;  
  48.       ll lo = 1;  
  49.       ll hi = 1e18;  
  50.       ll ans = -1;  
  51.       while (lo <= hi)  
  52.       {  
  53.             ll mid = lo + (hi - lo) / 2;  
  54.             ll cnt = digit_dp(mid*2) - digit_dp(mid);  
  55.             if (cnt == m)  
  56.             {  
  57.                   ans = mid;  
  58.                   hi = mid - 1;  
  59.             }  
  60.             else if (cnt < m) lo = mid + 1;  
  61.             else hi = mid - 1;  
  62.       }  
  63.       assert(ans != -1);  
  64.       cout << ans;  
  65. }  

Friday, April 5, 2019

[Toph] An Obvious Interactive Problem

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : An Obvious Interactive Problem
Source            : Toph
Category          : Interactive Problems
Algorithm         : Interactive Problems, Binary Search
Verdict           : Accepted
  1. #include "bits/stdc++.h"  
  2.   
  3. using namespace std;  
  4.   
  5. int main()  
  6. {  
  7.       ios_base::sync_with_stdio(false);  
  8.       cin.tie(nullptr);  
  9.       cout << fixed << setprecision(2);  
  10.   
  11.       int lo = 0;  
  12.       int hi = 1000000;  
  13.       while (lo <= hi)  
  14.       {  
  15.             int mid = lo + hi >> 1;  
  16.             cout << mid << endl;  
  17.             fflush(stdout);  
  18.             string s;  
  19.             cin >> s;  
  20.             if (s == "Bigger") lo = mid + 1;  
  21.             else if (s == "Smaller") hi = mid - 1;  
  22.             else break;  
  23.       }  
  24. }