Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "aliens.h"
- #include <vector>
- #include <algorithm>
- #include <stack>
- #include <cstdio>
- #include <cstring>
- #define X first
- #define Y second
- #define PB push_back
- using namespace std;
- typedef long long ll;
- typedef pair < int , int > pii;
- typedef vector < int > vi;
- typedef pair < ll, ll > pt;
- const int N = 1e5 + 500;
- const ll INF = 1e13;
- bool cmp(pii A, pii B){
- if(A.Y == B.Y) return A.X > B.X;
- return A.Y < B.Y;
- }
- int x[N], y[N], cnt[N], n, k, cur = 0;
- vector < pii > v;
- ll pref[N], dp[N], mst = -1;
- pt toc[N];
- vector < int > hl;
- ll cost(int l,int r){
- return (ll)(x[l] - y[r]) * (x[l] - y[r]) - (pref[r] - pref[l] + (ll)(y[l] - x[l]) * (y[l] - x[l]));
- }
- ll ccw(pt A, pt B, pt C){
- return (A.X) * (B.Y - C.Y) + B.X * (C.Y - A.Y) + C.X * (A.Y - B.Y);
- }
- void add(int X){
- for(;hl.size() >= 2 && ccw(toc[hl[hl.size() - 1]], toc[hl[hl.size() - 2]], toc[X]) <= 0;)
- hl.pop_back();
- hl.PB(X);
- cur = min(cur, (int)hl.size() - 1);
- }
- ll get(int i, ll x){
- return toc[hl[i]].X * x + toc[hl[i]].Y;
- }
- /**
- ll f(int i,int c){
- if(i == n) return (c > k) * INF;
- if(dp[i][c] != -1) return dp[i][c];
- ll ret = INF;
- for(int j = i;j < n;j++){
- ret = min(ret, f(j + 1, c + 1) + cost(i, j));
- }
- return dp[i][c] = ret;
- }
- **/
- ll f(ll cst,int fl = 0){
- hl.clear(); cur = 0;
- toc[n] = {-2 * x[0], -(ll)y[0] * y[0] + 2LL * x[0] * y[0]}; cnt[n] = 0;
- add(n);
- for(int i = 0;i < n;i++){
- while(cur + 1 < hl.size() && get(cur, y[i]) > get(cur + 1, y[i]))
- cur++;
- dp[i] = get(cur, y[i]) + (ll)y[i] * y[i] - pref[i] + cst;
- cnt[i] = cnt[hl[cur]] + 1;
- toc[i] = {-2 * x[i + 1], dp[i] - (ll)y[i + 1] * y[i + 1] + 2LL * x[i + 1] * y[i + 1] + pref[i + 1]};
- add(i);
- }
- if(fl) {
- //printf("%lld %lld CNT %d K %d\n", dp[n - 1] - (ll)k * cst, cst, cnt[n - 1], k);
- //return max(dp[n - 1] - (ll)k * cst, 0LL);
- return dp[n - 1] - (ll)k * cst;
- }
- if(cnt[n - 1] == k) mst = cst;
- return cnt[n - 1] < k;
- }
- ll take_photos(int nn, int m, int kk, vi r, vi cc) {
- k = kk; n = nn;
- for(int i = 0;i < n;i++){
- if(r[i] > cc[i]) swap(r[i], cc[i]);
- v.PB({r[i], cc[i] + 1});
- }
- sort(v.begin(), v.end(), cmp);
- stack < int > st;
- for(int i = 0;i < n;i++){
- //printf("{%d %d}\n", v[i].X, v[i].Y);
- for(;!st.empty() && v[st.top()].X >= v[i].X; st.pop());
- st.push(i);
- //printf("PUSH %d SZ %d\n", i, (int)st.size());
- }
- n = st.size();int c = st.size() - 1;
- k = min(k, n);
- //printf("NEW N %d\n", n);
- for(; c >= 0; c--, st.pop())
- x[c] = v[st.top()].X, y[c] = v[st.top()].Y;
- for(int i = 1;i < n;i++){
- pref[i] = pref[i - 1];
- if(y[i - 1] > x[i])
- pref[i] -= (ll)(x[i] - y[i - 1]) * (x[i] - y[i - 1]);
- pref[i] += (ll)(x[i] - y[i]) * (x[i] - y[i]);
- }
- ll bs = pref[n - 1] + (ll)(x[0] - y[0]) * (x[0] - y[0]);
- ll sol = INF;
- ll lo_cst = 0, hi_cst = INF;
- //printf("%lld\n:", bs);
- for(int i = 0;i < 65;i++){
- //break;
- ll mid = (lo_cst + hi_cst) / 2;
- if(!f(mid))
- lo_cst = mid + 1;
- else
- hi_cst = mid;
- }
- if(mst != -1)
- return f(mst , 1) + bs;
- return f(lo_cst , 1) + bs;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement