Advertisement
pb_jiang

T4 AC

May 18th, 2024
778
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.56 KB | None | 0 0
  1. using ll = long long;
  2.  
  3. class Solution {
  4.     int fpow(ll a, ll p, ll m) {
  5.         assert(p >= 0);
  6.         ll ret = 1;
  7.         ll cur = a;
  8.         while(p) {
  9.             if (p & 1)
  10.                 ret = ret * cur % m;
  11.             cur = cur * cur % m;
  12.             p >>= 1;
  13.         }
  14.         return int(ret % m);
  15.     }
  16.     ll gn(ll x) {
  17.         // count the number of elements of first 2^x strong arrays;
  18.         ll ret = 0;
  19.         // cout << "gn(" << x << "): ";
  20.         for (ll i = 0; i < x; ++i) ret = ret * 2 + (1ll << i);
  21.         // cout << ret << endl;
  22.         return ret;
  23.     }
  24.     ll hn(ll x) {
  25.         // count the sum of elements of first 2^x strong arrays;
  26.         ll ret = 0;
  27.         // cout << "hn(" << x << "): ";
  28.         for (ll i = 0; i < x; ++i) ret = ret * 2 + (1ll << i) * i;
  29.         // cout << ret << endl;
  30.         return ret;
  31.     }
  32.     ll fn(ll x) {
  33.         // cout << "\nx: " << x << endl;
  34.         ll ret = 0, rem = x, v = 0, lg_sum = 0;
  35.         for (ll i = 48, bits = 0; i >= 0; --i) {
  36.             ll ec = 1ll << i;
  37.             ll picked_num = bits * ec, pick_val = lg_sum * ec + hn(i);
  38.             ll num_it = gn(i) + picked_num;
  39.             if (num_it > rem) {
  40.                 continue;
  41.             } else {
  42.                 // cout << "rem: " << rem << " num_it: " << num_it << " ec: " << ec << " gn(i): " << gn(i) << " picked_num: " << picked_num << " bits: " << bits << " pick_val: " << pick_val << " lg_sum: " << lg_sum << endl;
  43.                 rem -= num_it;
  44.                 bits += 1;
  45.                 v |= ec;
  46.                 lg_sum += i;
  47.                 ret += pick_val;
  48.             }
  49.         }
  50.         // cout << "rem: " << rem << " ret: " << ret << " x:" << x << " v: " << v << endl;
  51.         if (rem) {
  52.             // v += 1;
  53.             while(rem && v) {
  54.                 ret += __builtin_ctzll(v & -v);
  55.                 v = v & (v - 1);
  56.                 rem -= 1;
  57.             }
  58.         }
  59.         cout << "fn(" << x << "): " << ret << endl;
  60.         return ret;
  61.     }
  62.     ll g(ll x) {
  63.         // count the number of elements of first x strong array given x = 2^n;
  64.         if (x == 0)  return 0;
  65.         ll ret = 0;
  66.         for (ll i = 0, v = 0; i <= x; i <<= 1, v += 1) {
  67.             ret = ret * 2 + i;
  68.         }
  69.         return ret;
  70.     }
  71.     ll h(ll x) {
  72.         // count the sum of elements of first x strong array given x = 2^n;
  73.         // return (x - 1) * x / 2;
  74.         ll t = x / 2;
  75.         return (t + 1) * t;
  76.     }
  77.     ll f(ll x) {
  78.         // count the sum of elements of first x elements in big_nums;
  79.         cout << "\nx: " << x << endl;
  80.         if (x == 0) return 1;
  81.         ll ret = 0, rem = x, v = 0, lg_sum = 0;
  82.         for (ll i = 31, bits = 0; i >= 0; --i) {
  83.             ll ec = 1ll << i;
  84.             ll picked_num = bits * ec, pick_val = lg_sum * g(ec) + h(ec);
  85.             ll num_it = g(ec) + picked_num;
  86.             if (num_it > rem) {
  87.                 continue;
  88.             } else {
  89.                 cout << "rem: " << rem << " num_it: " << num_it << " ec: " << ec << " g(ec): " << g(ec) << " picked_num: " << picked_num << " bits: " << bits << " pick_val: " << pick_val << " lg_sum: " << lg_sum << endl;
  90.                 rem -= num_it;
  91.                 bits += 1;
  92.                 v |= ec * 2;
  93.                 lg_sum += i + 1;
  94.                 ret += pick_val;
  95.             }
  96.         }
  97.         cout << "\nrem: " << rem << " ret: " << ret << " x:" << x << " v: " << v << endl;
  98.         // rem -= 1;
  99.         if (rem) {
  100.             v += 1;
  101.             while(rem && v) {
  102.                 // cout << rem << endl;
  103.                 ret += __builtin_ctz(v & -v);
  104.                 v = v & (v - 1);
  105.                 rem -= 1;
  106.             }
  107.         }
  108.         cout << "f(" << x << "): " << ret <<endl;
  109.         return ret;
  110.     }
  111. public:
  112.     vector<int> findProductsOfElements(vector<vector<long long>>& qs) {
  113.         assert(gn(0) == 0), assert(gn(1) == 1), assert(gn(2) == 4), assert(gn(5) == 80);
  114.         assert(hn(0) == 0), assert(hn(1) == 0), assert(hn(2) == 2), assert(hn(3) == 12), assert(hn(4) == 48), assert(hn(5) == 160);
  115.         // cout << "g(8): " << g(8) << " h(8): " << h(8) << endl;
  116.         // cout << "f(2): " << f(2) << endl;
  117.         // cout << "f(5): " << f(5) << endl;
  118.         // cout << "fn(40): " << fn(40) << endl;
  119.         int n = qs.size();
  120.         vector<int> ret(n);
  121.         for (int i = 0; i < n; ++i) {
  122.             ll l = qs[i][0], r = qs[i][1], m = qs[i][2];
  123.             // cout << "i: " << i << endl;
  124.             ret[i] = fpow(2, fn(r + 1) - fn(l), m);
  125.         }
  126.         return ret;
  127.     }
  128. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement