Submission #206683

#TimeUsernameProblemLanguageResultExecution timeMemory
206683mieszko11bAliens (IOI16_aliens)C++14
100 / 100
243 ms11828 KiB
#include "aliens.h"
#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using ld = long double;
using pll = pair<ll, ll>;

#define X first
#define Y second

ll INF = 1e18;
ld EPS = 1e-10;

inline ll sq(ll x) {
	return 2LL * x * x;
}

struct Parabolas {
	int ind = 0;
	vector<ll> A, B, C;
	
	ld intersection(ll a, ll b, ll c, ll d) {
		return (ld(sq(c) + d - sq(a) - b) / ld(2LL * c - 2LL * a));
	}
	
	bool ok(ll a, ll b, ll c, ll d) {
		if(a == c)
			return false;
		//~ cout << "ok" << (ld(sq(c) + d - sq(a) - b) / ld(2LL * c - 2LL * a)) + EPS << endl;
		return intersection(a, b, c, d) + EPS > max(a, c);
	}
	
	void clear() {
		ind = 0;
		A.clear();
		B.clear();
		C.clear();
	}
	
	void insert(ll a, ll b, ll c) {
		//~ cout << "ins"<<a << " "<< b << endl;
			
		while((!A.empty() && !ok(A.back(), B.back(), a, b))
			|| (A.size() >= 2 && intersection(A[A.size()-2], B[B.size()-2], A.back(), B.back()) > intersection(a, b, A.back(), B.back())) ){
			A.pop_back();
			B.pop_back();
			C.pop_back();
			if(ind == A.size()) ind--;
		}
		ind = max(ind, 0);
		
		A.push_back(a);
		B.push_back(b);
		C.push_back(c);
	}
	
	//~ ll query(ll x) {
		//~ ll res = INF;
		//~ for(int i = 0 ; i < A.size() ; i++)
			//~ res=  min(res, sq(x-A[i]) + B[i]);
		//~ return res;
	//~ }
	
	pll query(ll x) {
		if(A.size() == 0)
			return {INF, INF};
			
		while(ind + 1 < A.size() && sq(x - A[ind + 1]) + B[ind + 1] <= sq(x - A[ind]) + B[ind])
			ind++;
			
		//~ for(int i = 0 ; i < A.size() ; i++)
			//~ cout << "(" << A[i] << ", " << B[i] << ": " << sq(x - A[i]) + B[i] << ") ";
		//~ cout << endl << "x=" << x << " ind=" << ind << endl;
			
		return {sq(x - A[ind]) + B[ind], C[ind] + 1};
	}
};

int l, k;
int d[100007], x[100007];
int maxx[1000007];
Parabolas P;
pll dp[100007]; // n => {res, parts}

pll calc_dp(ll alfa) {
	for(int i = 0 ; i < 100007 ; i++)
		dp[i] = {INF, INF};
		
	dp[0] = {0, 0};
	P.clear();
	for(int i = 0 ; i <= l ; i++) {
		if(i > 0)
			dp[i] = P.query(x[i]);
		//~ cout << i << " " << j << " " << dp[j][i] << endl;
		if(i < l && dp[i].X != INF)
			P.insert(d[i + 1] - 1, dp[i].X - sq(max(0, x[i] - d[i + 1] + 1)) + alfa, dp[i].Y);
	}
	
	if(alfa <= 0) {
		dp[l].X += alfa * (k - dp[l].Y);
		dp[l].Y = k;
	}
	
	return dp[l];
}

long long take_photos(int n, int m, int k, std::vector<int> r, std::vector<int> c) {
	::k = k;
	
	for(int i = 0 ; i < n ; i++) {
		if(c[i] >= r[i]) maxx[r[i] + 1] = max(maxx[r[i] + 1], c[i] + 1);
		else maxx[c[i] + 1] = max(maxx[c[i] + 1], r[i] + 1);
	}
	
	for(int i = 1 ; i <= m ; i++) {
		if(maxx[i] && (l == 0 || x[l] < maxx[i])) {
			l++;
			d[l] = i;
			x[l] = maxx[i];
			//~ cout << d[l] << " " << x[l] << endl;
		}
	}
	
	ll pocz = 0, kon = ll(2e12), mid;
	while(pocz < kon) {
		mid = (pocz + kon) / 2;
		pll p = calc_dp(2LL * mid - 1);
		if(p.Y <= k)
			kon = mid;
		else
			pocz = mid + 1;
	}

	pll p = calc_dp(2LL * pocz - 1);
	ll res = (p.X - p.Y * (2LL * pocz - 1)) / 2LL;
	if(p.Y < k) {
		pll p2 = calc_dp(2LL * pocz - 3);
		ll res2 = (p2.X - p2.Y * (2LL * pocz - 3)) / 2LL;
		
			//~ cout << 2LL * pocz - 1 << " "<< p.X << " " << p.Y << " " << res<<endl;
			//~ cout << 2LL * pocz - 3 << " "<< p2.X << " " << p2.Y << " " << res2<<endl;
		
		return res - (res - res2) / (p2.Y - p.Y) * (k - p.Y);
	}
	//~ cout << p.X << " " << p.Y << endl;
	
	return res;
}

Compilation message (stderr)

aliens.cpp: In member function 'void Parabolas::insert(ll, ll, ll)':
aliens.cpp:50:11: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    if(ind == A.size()) ind--;
       ~~~~^~~~~~~~~~~
aliens.cpp: In member function 'pll Parabolas::query(ll)':
aliens.cpp:70:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   while(ind + 1 < A.size() && sq(x - A[ind + 1]) + B[ind + 1] <= sq(x - A[ind]) + B[ind])
         ~~~~~~~~^~~~~~~~~~
#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...