abeepbeepsheep

Untitled

Aug 28th, 2023
313
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.82 KB | Source Code | 0 0
  1. //N,K<1e5, meaning that the final answer might overflow long long
  2. #include <bits/stdc++.h>
  3. #include <ext/pb_ds/assoc_container.hpp>
  4. #include <ext/pb_ds/tree_policy.hpp>
  5. using namespace std;
  6. using namespace __gnu_pbds;
  7.  
  8. typedef tree<long long, null_type, less_equal<>,
  9.         rb_tree_tag, tree_order_statistics_node_update>
  10.         ordered_set;
  11. #define ll long long
  12. #define ii pair<ll,ll>
  13.  
  14. #ifndef DEBUG
  15. #define cerr if (0) cerr
  16. #define endl '\n'
  17. #endif
  18. const ll maxn=1e5+5;
  19. const ll mod=1e9+7;
  20.  
  21. mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  22. #ifndef WIN32
  23. #define int __int128
  24. #define ll __int128
  25. #define getchar getchar_unlocked
  26. #endif
  27. int read() {
  28.     int x = 0, f = 1;
  29.     char ch = getchar();
  30.     while (ch < '0' || ch > '9') {
  31.         if (ch == '-') f = -1;
  32.         ch = getchar();
  33.     }
  34.     while (ch >= '0' && ch <= '9') {
  35.         x = x * 10 + ch - '0';
  36.         ch = getchar();
  37.     }
  38.     return x * f;
  39. }
  40. void print(int x) {
  41.     if (x < 0) {
  42.         putchar('-');
  43.         x = -x;
  44.     }
  45.     if (x > 9) print(x / 10);
  46.     putchar(x % 10 + '0');
  47. }
  48. const int inf=4'000'000'000'000'000'000'000;
  49. ll arr[maxn];
  50. ll dp[maxn],cnt[maxn];
  51. deque<ii> dq; //transition point, start time
  52. ll n,k;
  53. ll W(ll i, ll j){
  54.     return (j-i+1)*(arr[j]-arr[i-1]);
  55. }
  56. ll solve(ll cost){
  57.     memset(dp,0,sizeof(dp)),memset(cnt,0,sizeof(cnt));
  58.     dq.clear();
  59.     for (int i=1;i<=n;i++){
  60.         if (dq.size()>=2 && dq[0].second==dq[1].second) dq.pop_front(); //the time has come
  61.         while (dq.size() && dp[dq.back().first-1]+W(dq.back().first,dq.back().second) >
  62.                 dp[i-1]+W(i,dq.back().second)){ // covers entire segment
  63.             dq.pop_back(); //if transitioning at i beats out current
  64.         }
  65.         if (dq.empty()){ //if there is nothing
  66.             dq.emplace_back(i,i); //starting now
  67.         } else{ // we have some segment {point, start}, we are at curr > point
  68.         //need to find a time X > start, such that dp[point-1]+W(point,X)>=dp[curr-1]+W(curr,X)
  69.             ll l=dq.back().second,r=n+1,m; //find where it is optimal to cut dp[1..i-1] + W[i..r]
  70.             while (l+1<r){
  71.                 m=(l+r)>>1;
  72.                 if (dp[dq.back().first-1]+W(dq.back().first,m)>dp[i-1]+W(i,m)){
  73.                     r=m; //win, move towards left
  74.                 } else l=m; //lose, move towards right
  75.             }
  76.             if (r!=n+1){
  77.                 dq.emplace_back(i,r);
  78.             }
  79.         }
  80.         dp[i]=W(dq.front().first,i)+dp[dq.front().first-1]+cost; // dp[1..X-1] + W[X..Y] + cost
  81.         cnt[i]=cnt[dq.front().first-1]+1; //number of segments taken
  82.         if (dq.front().second==i) dq.front().second++; //update index to next one
  83.     }
  84.     return cnt[n];
  85. }
  86. signed main(){
  87.     ios_base::sync_with_stdio(0);
  88.     cin.tie(0);
  89.     n=read(),k=read();
  90.     for (int i=1;i<=n;i++){
  91.         arr[i]=read();
  92.         arr[i]+=arr[i-1];
  93.     }
  94.     ll l=0,r=inf,m;
  95.     ll ans=0;
  96.     while (l!=r-1){
  97.         m=(l+r)>>1;
  98.         if (solve(m)>k){
  99.             l=m;
  100.         } else{
  101.             ans=dp[n]-k*m;
  102.             r=m;
  103.         }
  104.     }
  105.     print(ans);
  106.     return 0;
  107. }
Advertisement
Add Comment
Please, Sign In to add comment