이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
// Black lives matter
#include <bits/stdc++.h>
#include "aliens.h"
/// 500 485 462 A4
using namespace std;
typedef long long int ll;
typedef complex<double> point;
typedef long double ld;
#define pb push_back
#define pii pair < ll , ll >
#define F first
#define S second
//#define endl '\n'
#define int long long
#define sync ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#define kill(x) return cout<<x<<'\n', 0;
const int N=5e3+10,M=1e6+100,inf=(ll)1e15;
ll dp[N][N];
ll A[M];
vector <pii> B;
/*
void solve(ll l,ll r,ll L,ll R,ll k){
if (r<l) return;
ll mid=(r+l)/2;
ll id=0,mx=inf;
for (int i=L;i<=min(R,mid);i++){
ll z=0;
if (i>1){
if (B[i-1].F<B[i-2].S){
z=(B[i-2].S-B[i-1].F)*((B[i-2].S-B[i-1].F));
}
}
ll x=dp[i-1][(k-1)%2]+(B[mid-1].S-B[i-1].F)*(B[mid-1].S-B[i-1].F)-z;
if (mx>x){
mx=x;
id=i;
}
}
dp[mid][k%2]=mx;
// cout << l << " " << r << " " << mid << " " << k << " " << mx << endl;
solve(l,mid-1,L,id,k);
solve(mid+1,r,id,R,k);
}
*/
vector <pair <int,pii> > line;
ll intersect(pii x,pii y){
if (x.F==y.F){
if (x.S<=y.S) return -inf;
else return inf;
}
return (y.S-x.S)/(x.F-y.F)+((y.S-x.S)%(x.F-y.F)>0);
}
void add(pii x){
while(line.size()){
pii y=line.back().S;
ll z=intersect(x,y);
if (z<=line.back().F){
line.pop_back();
}
else{
line.pb({z,x});
return ;
}
}
line.pb({-inf,x});
}
ll get(ll x){
auto t=lower_bound(line.begin(),line.end(),pair <int,pii>({x,{inf,inf}}))-line.begin();
t--;
pii p=line[t].S;
return x*p.F+p.S;
}
long long take_photos(int32_t n, int32_t m, int32_t k, std::vector<int32_t> r, std::vector<int32_t> c){
for (int i=0;i<M;i++) A[i]=i;
for (int i=0;i<n;i++){
ll x=r[i],y=c[i];
A[max(x,y)]=min(A[max(x,y)],min(x,y)-1);
}
for (int i=0;i<m;i++){
if (A[i]<i){
while(B.size() && B.back().F>=A[i]) B.pop_back();
B.pb({A[i],i});
}
}
// for (auto u : B){
// cout << u.F << " " << u.S << endl;
//}
ll t=B.size();
for (int i=1;i<=t;i++){
dp[i][1]=(B[i-1].S-B[0].F)*(B[i-1].S-B[0].F);
}
for (int i=2;i<=k;i++){
dp[1][i]=dp[1][1];
for (int j=2;j<=t;j++){
ll z=0;
if (B[j-1].F<B[j-2].S){
z=(B[j-2].S-B[j-1].F)*((B[j-2].S-B[j-1].F));
}
add({2*B[j-1].F,-(dp[j-1][i-1]-z+B[j-1].F*B[j-1].F)});
// cout << z << " " << dp[j-1][i-1] << " " << B[j-1].F << " " << B[j-1].S << " " << get(B[j-1].S)<< endl;
dp[j][i]=-get(B[j-1].S)+B[j-1].S*B[j-1].S;
}
}
return dp[t][k];
}
/*
int32_t main() {
int n, m, k;
assert(3 == scanf("%d %d %d", &n, &m, &k));
std::vector<int32_t> r(n), c(n);
for (int i = 0; i < n; i++) {
assert(2 == scanf("%d %d", &r[i], &c[i]));
}
long long ans = take_photos(n, m, k, r, c);
printf("%lld\n", ans);
return 0;
}
*/
/*
5 7 2
0 3
4 4
4 6
4 5
4 6
*/
//take_photos(5, 7, 2, [0, 4, 4, 4, 4], [3, 4, 6, 5, 6])
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |