Advertisement
welleyth

D. VKOSHP 2022

Dec 9th, 2022
989
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.50 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #include <ext/pb_ds/assoc_container.hpp>
  3. #include <ext/pb_ds/tree_policy.hpp>
  4.  
  5. using namespace std;
  6. using namespace __gnu_pbds;
  7.  
  8. //#define int long long
  9. #define mp make_pair
  10. #define pb push_back
  11.  
  12. #pragma GCC optimize("Ofast")
  13. #pragma GCC optimize("unroll-loops")
  14. #pragma GCC target("avx2")
  15.  
  16. typedef long long ll;
  17.  
  18. constexpr int N = (int)1e6+11;
  19. constexpr __int128 INF = (__int128)2e18*(__int128)1e10+111;
  20. constexpr int md = (int)1e9+7;
  21. constexpr int K = (int)60;
  22.  
  23. void add(int& a,int b){
  24.     a = (a+b >= md ? a+b-md : a+b);
  25. }
  26. void sub(ll& a,ll b){
  27.     a = (a-b < 0 ? a-b+md : a-b);
  28. }
  29.  
  30. mt19937 rnd(time(nullptr));
  31.  
  32. struct Line {
  33.     int k;
  34.     __int128 b;
  35.  
  36.     Line(int k, __int128 b): k(k), b(b) {}
  37.  
  38.     Line(): k(0), b(INF) {}
  39.  
  40.     __int128 operator()(__int128 x) {
  41.         return k * x + b;
  42.     }
  43. };
  44.  
  45. struct LiChaoSegmentTree {
  46.     static const ll T = (1 << 23);
  47.  
  48.     ll ptr = 2;
  49. //    Line tree[T];
  50. //    ll L[T],R[T];
  51.     struct node{
  52.         Line L;
  53.         node *l = nullptr, *r = nullptr;
  54.         node(){}
  55.         void createL(){
  56.             if(l == nullptr){
  57.                 l = new node();
  58.             }
  59.         }
  60.         void createR(){
  61.             if(r == nullptr){
  62.                 r = new node();
  63.             }
  64.         }
  65.     };
  66. //    unordered_map<ll,Line> T;
  67.  
  68.     ll n;
  69.     node* rt;
  70.  
  71.     void init(ll len) {
  72.         n = len;
  73. //        for(ll i = 0; i < T; i++)
  74. //            L[i] = -1, R[i] = -1;
  75.         rt = new node();
  76.         return;
  77.     }
  78.  
  79.     void insertLine(node* v, ll l, ll r, Line newLine) {
  80.         bool dominateLeft = (newLine(l) < v->L(l));
  81.         ll mid = (1ll*r + l) / 2;
  82.         bool dominateMid = (newLine(mid) < v->L(mid));
  83.         if (dominateMid) {
  84.             swap(newLine, v->L);
  85.         }
  86.         if (l + 1 == r) {
  87.             return;
  88.         }
  89.         if (dominateLeft == dominateMid) {
  90.             v->createL();
  91.             insertLine(v->l, mid, r, newLine);
  92.         } else {
  93.             v->createR();
  94.             insertLine(v->r, l, mid, newLine);
  95.         }
  96.     }
  97.  
  98.     void insertLineOnSegment(node* v, ll l, ll r, ll ql, ll qr, Line newLine) {
  99.         if (r <= ql || qr <= l) {
  100.             return;
  101.         }
  102.         if (ql <= l && r <= qr) {
  103.             insertLine(v, l, r, newLine);
  104.             return;
  105.         }
  106.         ll mid = (1ll*r + l) / 2;
  107.         v->createL();
  108.         v->createR();
  109.         insertLineOnSegment(v->l, l, mid, ql, qr, newLine);
  110.         insertLineOnSegment(v->r, mid, r, ql, qr, newLine);
  111.     }
  112.  
  113.     void insertLineOnSegment(ll ql, ll qr, Line newLine) {
  114.         insertLineOnSegment(rt, 0, n, ql, qr, newLine);
  115.     }
  116.  
  117.     __int128 getValue(node* v, ll l, ll r, ll pos) {
  118.         __int128 ans = v->L(pos);
  119.         if (l + 1 != r) {
  120.             ll mid = (1ll*r + l) / 2;
  121.             if (pos < mid) {
  122.                 v->createL();
  123.                 ans = min(ans, getValue(v->l, l, mid, pos));
  124.             } else {
  125.                 v->createR();
  126.                 ans = min(ans, getValue(v->r, mid, r, pos));
  127.             }
  128.         }
  129.         return ans;
  130.     }
  131.  
  132.     __int128 getValue(ll pos) {
  133.         return getValue(rt, 0, n, pos);
  134.     }
  135.     void fullDelete(node* v){
  136.         if(v->l != nullptr)
  137.             fullDelete(v->l);
  138.         if(v->r != nullptr)
  139.             fullDelete(v->r);
  140.         delete v;
  141.     }
  142.     void DeleteTree(node* v,ll l,ll r,ll tl,ll tr,node* pr){
  143.         if (r <= tl || tr <= l) {
  144.             return;
  145.         }
  146.         if (tl <= l && r <= tr) {
  147.             if(pr->l == v)
  148.                 pr->l = nullptr;
  149.             if(pr->r == v)
  150.                 pr->r = nullptr;
  151.             fullDelete(v);
  152.             return;
  153.         }
  154.         ll m = (l+r)>>1;
  155.         if(v->l != nullptr)
  156.             DeleteTree(v->l,l,m,tl,min(tr,m),v);
  157.         if(v->r != nullptr)
  158.             DeleteTree(v->r,m,r,max(tl,m),tr,v);
  159.         return;
  160.     }
  161.     void DeleteTree(ll l,ll r){
  162.         node* pr = nullptr;
  163.         DeleteTree(rt,0,n,l,r,pr);
  164.         return;
  165.     }
  166.  
  167. } segTree;
  168.  
  169. void solve(){
  170.     long long n,B,C;
  171.     cin >> n >> B >> C;
  172.  
  173.     long long x[n+1],p[n+1];
  174.     x[0] = 0;
  175.     for(ll i = 1; i <= n; i++){
  176.         cin >> x[i] >> p[i];
  177.     }
  178.  
  179.     segTree.init((long long)3e9+10);
  180.  
  181.     segTree.insertLineOnSegment(0,1,Line(0,0));
  182.     ll last = 0;
  183.  
  184.     for(ll i = 1; i <= n; i++){
  185.         segTree.DeleteTree(x[i-1],x[i]-1);
  186.         __int128 prVal = segTree.getValue(x[i]);
  187.         if(prVal > B)
  188.             break;
  189.         segTree.insertLineOnSegment(x[i],min((long long)3e9+10,x[i]+C+1),Line(p[i],prVal-p[i]*(x[i])));
  190.         prVal = segTree.getValue(last);
  191.         if(prVal > B)
  192.             continue;
  193.         segTree.insertLineOnSegment(last,min((ll)3e9+10,x[i]+C+1),Line(p[i],prVal-p[i]*(last)));
  194.         last = x[i] + C;
  195.     }
  196.  
  197. //    for(ll i = 0; i < 10; i++){
  198. //        cout << (long long)segTree.getValue(i) << " ";
  199. //    }
  200. //    cout << "\n";
  201.  
  202.     long long l = 0, r = (long long)3e9 + 2;
  203.     while(r - l > 1){
  204.         ll m = (l+r)>>1;
  205.         if(segTree.getValue(m) > B)
  206.             r = m;
  207.         else
  208.             l = m;
  209.     }
  210.  
  211.     cout << l << "\n";
  212.  
  213.     return;
  214. }
  215.  
  216. signed main(){
  217.     ios::sync_with_stdio(false); cin.tie(nullptr);cout.tie(nullptr);
  218. //    freopen("input.txt","r",stdin);
  219. //    freopen("output.txt","w",stdout);
  220.     ll tests = 1;
  221. //    cin >> tests;
  222.     for(ll test = 1; test <= tests; test++){
  223.         solve();
  224.     }
  225.     return 0;
  226. }
  227. /**
  228. 10 10
  229. 0 1 2 3 5 6 7 8 9 11
  230. 1 2 3 4 5 6 7 8 9 10
  231. **/
  232.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement