제출 #119221

#제출 시각아이디문제언어결과실행 시간메모리
119221patrikpavic2Aliens (IOI16_aliens)C++17
100 / 100
194 ms9372 KiB
#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;
}






컴파일 시 표준 에러 (stderr) 메시지

aliens.cpp: In function 'll f(ll, int)':
aliens.cpp:72:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   while(cur + 1 < hl.size() && get(cur, y[i]) > get(cur + 1, y[i]))
         ~~~~~~~~^~~~~~~~~~~
aliens.cpp: In function 'll take_photos(int, int, int, vi, vi)':
aliens.cpp:114:8: warning: unused variable 'sol' [-Wunused-variable]
     ll sol = INF;
        ^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...