Dang_Quan_10_Tin

TESTROOMS (CSPTST 2022-2023)

Aug 19th, 2022 (edited)
804
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.86 KB | None | 0 0
  1. #define task "TESTROOMS"
  2. #include <iostream>
  3. #include <cstdio>
  4. #include <algorithm>
  5. #include <vector>
  6.  
  7. using namespace std;
  8.  
  9. using ll = long long;
  10. using ld = long double;
  11.  
  12. constexpr int N = 1e4 + 5;
  13. constexpr ll Inf = 1e17;
  14.  
  15. template <class T>
  16. void readInt(T &x)
  17. {
  18.     x = 0;
  19.     register int c;
  20.     while ((c = getchar()) && (c > '9' || c < '0'))
  21.         ;
  22.     for (; c >= '0' && c <= '9'; c = getchar())
  23.         x = x * 10 + c - '0';
  24. }
  25.  
  26. struct ConvexHullTrick
  27. {
  28.     ll A[N], B[N];
  29.     int piv, line[N], szline, szpoint;
  30.     ld point[N];
  31.  
  32.     ConvexHullTrick()
  33.     {
  34.         szline = 0;
  35.         szpoint = 0;
  36.         piv = 0;
  37.         point[szpoint++] = -Inf;
  38.     }
  39.  
  40.     void Reset()
  41.     {
  42.         szline = 0;
  43.         szpoint = 0;
  44.         piv = 0;
  45.         point[szpoint++] = -Inf;
  46.     }
  47.  
  48.     ld ff(int x, int y)
  49.     {
  50.         return (ld)1.0 * (B[x] - B[y]) / (A[y] - A[x]);
  51.     }
  52.  
  53.     void Add(int x)
  54.     {
  55.         while (szline > 1 || (szline == 1 && A[line[szline - 1]] == A[x]))
  56.         {
  57.             if (A[line[szline - 1]] == A[x])
  58.             {
  59.                 if (B[line[szline - 1]] <= B[x])
  60.                     break;
  61.                 else
  62.                 {
  63.                     --szline;
  64.                     if (!szline == 0)
  65.                         --szpoint;
  66.  
  67.                     piv = min(piv, szpoint - 1);
  68.                 }
  69.             }
  70.             else
  71.             {
  72.                 if (ff(line[szline - 1], x) <= ff(x, line[szline - 2]))
  73.                 {
  74.                     --szline;
  75.                     if (!szline == 0)
  76.                         --szpoint;
  77.  
  78.                     piv = min(piv, szpoint - 1);
  79.                 }
  80.                 else
  81.                     break;
  82.             }
  83.         }
  84.  
  85.         if (szline == 0 || A[line[szline - 1]] != A[x])
  86.         {
  87.             if (szline != 0)
  88.                 point[szpoint++] = ff(x, line[szline - 1]);
  89.             line[szline++] = x;
  90.         }
  91.     }
  92.  
  93.     int Get(ll x)
  94.     {
  95.         while (piv < szpoint && point[piv] <= x)
  96.             ++piv;
  97.  
  98.         return line[piv - 1];
  99.     }
  100. } calf, calg;
  101.  
  102. int n, k;
  103. ll a[N], x[N], f[N], g[N], f1[N];
  104.  
  105. void Read()
  106. {
  107.     // cin >> n >> k;
  108.     readInt(n), readInt(k);
  109.  
  110.     for (int i = 1; i <= n; ++i)
  111.         // cin >> x[i];
  112.         readInt(x[i]);
  113. }
  114.  
  115. void Solve()
  116. {
  117.     sort(x + 1, x + n + 1);
  118.  
  119.     for (int i = 1; i <= n; ++i)
  120.     {
  121.         a[i] = a[i - 1] + x[i];
  122.         f1[i] = f1[i - 1] + x[i] - x[(i + 1) / 2];
  123.     }
  124.  
  125.     for (int j = 2; j <= k; ++j)
  126.     {
  127.         for (int i = j - 1; i <= n; ++i)
  128.         {
  129.             if (i >= j)
  130.             {
  131.                 int optg = calg.Get(x[i]);
  132.  
  133.                 g[i] = f1[optg] + x[i] * (i - optg) - (a[i] - a[optg]);
  134.                 calf.A[i] = -x[i];
  135.                 calf.B[i] = g[i] - a[i] + x[i] * i;
  136.                 calf.Add(i);
  137.  
  138.                 int optf = calf.Get(i);
  139.                 f[i] = g[optf] + (a[i] - a[optf]) - x[optf] * (i - optf);
  140.             }
  141.  
  142.             // cout << f[i] << (i == n ? "\n" : " ");
  143.  
  144.             calg.A[i] = -i;
  145.             calg.B[i] = f1[i] + a[i];
  146.             calg.Add(i);
  147.         }
  148.  
  149.         calf.Reset();
  150.         calg.Reset();
  151.         swap(f, f1);
  152.     }
  153.  
  154.     cout << f1[n];
  155. }
  156.  
  157. int32_t main()
  158. {
  159.     ios_base::sync_with_stdio(0);
  160.     cin.tie(0);
  161.     cout.tie(0);
  162.  
  163.     if (fopen(task ".INP", "r"))
  164.     {
  165.         freopen(task ".INP", "r", stdin);
  166.         freopen(task ".OUT", "w", stdout);
  167.     }
  168.  
  169.     Read();
  170.     Solve();
  171. }
  172.  
  173. /*
  174. 5 5
  175. 1 1 2 3 5
  176. */
  177.  
  178. /*
  179. g(i) + (a_t - a_i) - x_i * (t - i) < g(j) + (a_t - a_j) - x_j * (t - j)
  180. g(i) - a_i + i * x_i - x_i * t < g(j) - a_j + j * x_j - x_j * t
  181.  
  182.  
  183.  
  184. f(i) + x_t * (t - i) - (a_t - a_i) < f(j) + x_t * (t - j) - (a_t - a_j)
  185. f(i) - x_t * i + a_i < f(j) - x_t * j + a_j
  186.  
  187. Khi f(t) va g(t) dat min, y=at + b cung dat min => Convexhull trick
  188. */
Advertisement
Add Comment
Please, Sign In to add comment