prog3r

Link-Cut Пельмени

Oct 7th, 2024
247
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.64 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. using vbo = vector<bool>;
  4. using ll = long long;
  5. using pll = pair<ll, ll>;
  6. using ld = long double;
  7. using qll = queue<ll>;
  8. using vll = vector<ll>;
  9. using vvll = vector<vector<ll>>;
  10. using qld = queue<ld>;
  11. using vld = vector<ld>;
  12. using qpll = queue<pll>;
  13. using vpll = vector<pll>;
  14. #define watch(x) clog << #x << " equals " << x << endl;
  15. #define all(value) value.begin(), value.end()
  16. #define fo(XX, X, fi) for(ll XX = X; XX < fi; XX++)
  17. #define forr(XX, X, fi) for(ll XX = X; XX <= fi; XX++)
  18. #define roff(XX, X, fi) for(ll XX = X; XX >= fi; XX--)
  19. ostream& endl(ostream& os) {
  20.     return os << '\n';
  21. }
  22. #define vv(type,name,n,...) vector<vector<type>> name(n,vector<type>(__VA_ARGS__))
  23. #define vvv(type,name,n,m,...) vector<vector<vector<type>>> name(n,vector<vector<type>>(m,vector<type>(__VA_ARGS__)))
  24. #define vvvv(type,name,n,m,k,...) vector<vector<vector<vector<type>>>> name(n,vector<vector<vector<type>>>(m,vector<vector<type>>(k, vector<type>(__VA_ARGS__))))
  25. #define vvvvv(type,name,n,m,k,l,...) vector<vector<vector<vector<vector<type>>>>> name(n,vector<vector<vector<vector<type>>>>(m,vector<vector<vector<type>>>(k, vector<vector<type>>(l, vector<type>(__VA_ARGS__)))))
  26. #define LL(...) \
  27.   ll __VA_ARGS__; \
  28.   IN(__VA_ARGS__)
  29. #define fi first
  30. #define se second
  31. template <class T, class S> inline bool chmax(T &a, const S &b) { return (a < b ? a = b, 1 : 0); }
  32. template <class T, class S> inline bool chmin(T &a, const S &b) { return (a > b ? a = b, 1 : 0); }
  33. template <typename T, typename U>
  34. ostream& operator<<(ostream& os, const pair<T, U>& A) {
  35.     os << A.fi << " " << A.se;
  36.     return os;
  37. }
  38. template <typename T>
  39. ostream& operator<<(ostream& os, const vector<T>& A) {
  40.     for (size_t i = 0; i < A.size(); i++) {
  41.         if(i) os << " ";
  42.         os << A[i];
  43.     }
  44.     return os;
  45. }
  46. void scan(int &a) { cin >> a; }
  47. void scan(long long &a) { cin >> a; }
  48. void scan(char &a) { cin >> a; }
  49. void scan(double &a) { cin >> a; }
  50. void scan(long double &a) { cin >> a; }
  51. void scan(string &a) { cin >> a; }
  52. template <class T, class S> void scan(pair<T, S> &p) { scan(p.first), scan(p.second); }
  53. template <class T> void scan(vector<T> &a) {for(auto &i : a) scan(i);}
  54. template <class T> void scan(T &a) { cin >> a; }
  55. void IN() {}
  56. template <class Head, class... Tail> void IN(Head &head, Tail &...tail) {
  57.     scan(head);
  58.     IN(tail...);
  59. }
  60. void print() {
  61.     cout << "\n";
  62. }
  63. template <class Head, class... Tail>
  64. void print(Head&& head, Tail&&... tail) {
  65.     cout << head;
  66.     if (sizeof...(Tail)) cout << " ";
  67.     print(forward<Tail>(tail)...);
  68. }
  69. #ifdef LOCAL
  70. #include <algo/debug.h>
  71. #else
  72. //#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,no-stack-protector,fast-math,trapv")
  73. #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,no-stack-protector,fast-math")
  74. #endif
  75. mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  76. uniform_int_distribution<ll> distrib(0ll, 1e9);
  77. constexpr ll MOD = 1e9+7;
  78. //constexpr ll MOD = 1e9+7;
  79. void in(vector<ll> & a) {
  80.     for (auto & x : a) cin >> x;
  81. }
  82. void in(vector<ll> & a, ll l, ll r) {
  83.     for (ll i=l; i < r; i+=1) {
  84.         cin >> a[i];
  85.     }
  86. }
  87. void inn(vector<ll> & a, ll l, ll rr) {
  88.     for (ll i=l; i <= rr; i+=1) {
  89.         cin >> a[i];
  90.     }
  91. }
  92. ll powm(ll a, ll b) {
  93.     assert(b >= 0);
  94.     ll d = 1;
  95.     while (b) {
  96.         if (b&1) d = (d*a) % MOD;
  97.         b >>= 1;
  98.         a = (a*a) % MOD;
  99.     }
  100.     return d;
  101. }
  102. ll powm(ll a, ll b, ll MOD) {
  103.     assert(b >= 0);
  104.     ll d = 1;
  105.     while (b) {
  106.         if (b&1) d = (d*a) % MOD;
  107.         b >>= 1;
  108.         a = (a*a) % MOD;
  109.     }
  110.     return d;
  111. }
  112. ll poww(ll a, ll b) {
  113.     assert(b >= 0);
  114.     ll d = 1;
  115.     while (b) {
  116.         if (b&1) d = (d*a);
  117.         b >>= 1;
  118.         a = (a*a);
  119.     }
  120.     return d;
  121. }
  122. ld poww(ld a, ll b) {
  123.     assert(b >= 0);
  124.     ld d = 1;
  125.     while (b) {
  126.         if (b&1) d = (d*a);
  127.         b >>= 1;
  128.         a = (a*a);
  129.     }
  130.     return d;
  131. }
  132. ll mul(ll a, ll b) {
  133.     return (a*b)%MOD;
  134. }
  135. ll sum(ll a, ll b) {
  136.     return (a+b)%MOD;
  137. }
  138. ll sub(ll a, ll b) {
  139.     return (a-b+100*MOD)%MOD;
  140. }
  141. ll fj0dsq983gf8(ll index, vector<ll> & tree)  {
  142.     index += 1;
  143.     ll sum = 0;
  144.     while (index > 0) {
  145.         sum += tree[index-1];
  146.         index -= index & -index;
  147.     }
  148.     return sum;
  149. } // zero-indexed!!!
  150. ll get_sum_ft(ll left, ll right, vector<ll> & tree) {
  151.     ll n = (ll)tree.size();
  152.     if (!(left <= right)) return 0;
  153.     assert(left <= right);
  154.     if (right >= n) {
  155.         clog << "FENWICK ALERT: R >= tree.size() (IT'S ZERO INDEXED !!!)" << endl;
  156.         right = n-1;
  157.     }
  158.     ll ans = fj0dsq983gf8(right, tree);
  159.     if (left-1 >= 0) {
  160.         ans -= fj0dsq983gf8(left - 1, tree);
  161.     }
  162.     return ans;
  163. } // zero-indexed!!!
  164. void inc_ft(ll index, ll inc, vector<ll> & tree) {
  165.     ll n = (ll)tree.size();
  166.     assert(index >= 0);
  167.     assert(index < n);
  168.     index += 1;
  169.     while (index < n) {
  170.         tree[index] += inc;
  171.         index += index & -index;
  172.     }
  173. } // zero-indexed!!!
  174. void build_ft(vector<ll> & a, vector<ll> & tree) {
  175.     ll n = (ll)tree.size();
  176.     assert(tree.size() == a.size());
  177.     for (ll i = 0; i < n; i++) {
  178.         tree[i] += a[i];
  179.         ll r = i | (i + 1);
  180.         if (r < n) tree[r] += tree[i];
  181.     }
  182. } // zero-indexed!!!
  183. ll inv(ll i, ll m) {
  184.     if (i == 1) return 1; return m-((inv(m%i, i)*m)/i);
  185. }
  186. /*
  187. void copy_this () {
  188.     ll n; cin >> n;
  189.     ll n, k; cin >> n >> k;
  190.     ll n, q; cin >> n >> q;
  191.     ll a[n]; for (ll i=0; i < n; i+=1) cin >> a[i];
  192.     vector<ll> a(n); for (ll i=0; i < n; i+=1) cin >> a[i];
  193. }
  194. */
  195. void solve() {
  196.     ll l = 0;
  197.     ll r;
  198.     cin >> r;
  199.     vvvvv(pll, dp, 61, 2, 2, 2, 2, make_pair(0ll, 0ll));
  200.     unordered_map<ll, ll> cnt;
  201.     // dp[бит][x уже больше l][x уже меньше r][y уже больше l][y уже меньше r]
  202.     function<pll(ll, ll, ll, ll, ll)> count = [&](ll i, ll xl, ll xr, ll yl, ll yr) {
  203.         if (i < 0) return make_pair(0ll, 1ll);
  204.         if (dp[i][xl][xr][yl][yr] != make_pair(0ll, 0ll)) return dp[i][xl][xr][yl][yr]; // alrhvebeencalced
  205.         ll res = -1e9;
  206.         ll rescnt = -1e9;
  207.         ll lefthas0 = !((1ll << i)&l);
  208.         ll righthas0 = !((1ll << i)&r);
  209.         ll lefthas1 = ((1ll << i)&l);
  210.         ll righthas1 = ((1ll << i)&r);
  211.         vll ithbitofx;
  212.         vll ithbitofy;
  213.         if (lefthas0 || xl) {
  214.             // у икса может быть выключен iый бит
  215.             ithbitofx.push_back(0);
  216.         }
  217.         if (righthas1 || xr) {
  218.             // у икса может быть включен iый бит
  219.             ithbitofx.push_back(1);
  220.         }
  221.         if (lefthas0 || yl) {
  222.             // у игрека может быть выключен iый бит
  223.             ithbitofy.push_back(0);
  224.         }
  225.         if (righthas1 || yr) {
  226.             // у игрека может быть включен iый бит
  227.             ithbitofy.push_back(1);
  228.         }
  229.         for (const auto &xi : ithbitofx) {
  230.             for (const auto &yi : ithbitofy) {
  231.                 ll addition = ((xi|yi) << (i));
  232.                 ll nxl = xl;
  233.                 if (xi && lefthas0) {
  234.                     nxl = 1;
  235.                 }
  236.                 ll nxr = xr;
  237.                 if (!xi && righthas1) {
  238.                     nxr = 1;
  239.                 }
  240.                 ll nyl = yl;
  241.                 if (yi && lefthas0) {
  242.                     nyl = 1;
  243.                 }
  244.                 ll nyr = yr;
  245.                 if (!yi && righthas1) {
  246.                     nyr = 1;
  247.                 }
  248.                 pll go = count(i-1, nxl, nxr, nyl, nyr);
  249.                 if (go.first+addition > res) {
  250.                     res = go.first+addition;
  251.                     rescnt = go.second;
  252.                 } else if (go.first+addition == res) {
  253.                     rescnt = sum(rescnt, go.second);
  254.                 }
  255.             }
  256.         }
  257.         return dp[i][xl][xr][yl][yr]=make_pair(res, rescnt);
  258.     };
  259.     pll my_ans = count(60,0,0,0,0);
  260.     cout << 2*my_ans.first << " " << my_ans.second << endl;
  261. }
  262.  
  263. int32_t main(int32_t argc, char* argv[]) {
  264.     cout << setprecision(17);
  265.     bool use_fast_io = true;
  266.     for (int32_t i = 1; i < argc; ++i) {
  267.         if (string(argv[i]) == "-local-no-fast-io") {
  268.             use_fast_io = false;
  269. //            cout << "No fastIO" << endl;
  270.             break;
  271.         }
  272.     }
  273.     if (use_fast_io) {
  274.         ios::sync_with_stdio(false);
  275.         cin.tie(nullptr);
  276.         cout.tie(nullptr);
  277.         cerr.tie(nullptr);
  278.         clog.tie(nullptr);
  279.     }
  280.     ll tt = 1;
  281. //    cin >> tt;
  282.     while (tt--) {
  283.         solve();
  284.     }
  285.     return 0;
  286. }
Advertisement
Comments
  • prog3r
    1 year
    # text 0.44 KB | 0 0
    1. Тк чтобы сравнить два бинарных числа достаточно сравнить первый символ после совпадающего префикса
    2. Мы можем хранить состояние как
    3. // dp[бит][x уже больше l][x уже меньше r][y уже больше l][y уже меньше r]
    4. И идти по убыванию значимости битов (слева направо)
Add Comment
Please, Sign In to add comment