This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
//template
#define rep(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define ALL(v) (v).begin(),(v).end()
using ll=long long int;
const int inf = 0x3fffffff; const ll INF = 0x1fffffffffffffff; const double eps=1e-12;
template<typename T>inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
template<typename T>inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;}
//end
struct CHT{
int n; vector<ll> xs,p,q; vector<bool> used;
CHT(const vector<ll>& ps){
n=1; while(n<(int)ps.size())n<<=1;
used.assign(4*n,0); xs.resize(4*n,inf);
p.resize(4*n); q.resize(4*n);
rep(i,0,ps.size())xs[i]=ps[i];
}
void add(ll a,ll b,int k=0,int l=0,int r=-1){
if(r==-1)r=n;
while(r-l>0){
int m=(l+r)>>1;
if(!used[k]){
p[k]=a; q[k]=b; used[k]=1;
return;
}
ll lx=xs[l],mx=xs[m],rx=xs[r-1];
ll pk=p[k],qk=q[k];
bool lb=(a*lx+b<pk*lx+qk);
bool mid=(a*mx+b<pk*mx+qk);
bool rb=(a*rx+b<pk*rx+qk);
if(lb&&rb){p[k]=a; q[k]=b; return;}
if(!lb&&!rb)return;
if(mid){swap(p[k],a); swap(q[k],b);}
if(lb!=mid){k=2*k+1; r=m;} else{k=2*k+2; l=m;}
}
}
void add_segment(ll a,ll b,int l,int r){
ll l0=l+n,r0=r+n,s0=l,t0=r,sz=1;
while(l0<r0){
if(r0&1){r0--; t0-=sz; add(a,b,r0-1,t0,t0+sz);}
if(l0&1){add(a,b,l0-1,s0,s0+sz); l0++; s0+=sz;}
l0>>=1; r0>>=1; sz<<=1;
}
}
pair<ll,ll> query(int i){
int k=i+n-1;
ll ami=-1,x=xs[i],s=INF;
if(used[k]){
s=p[k]*x+q[k];
ami=p[k];
}
while(k){
k=(k-1)>>1;
if(used[k]){
if(chmin(s,p[k]*x+q[k]))ami=p[k];
}
} return {s,ami};
}
};
long long take_photos(int n, int m, int k, std::vector<int> r, std::vector<int> c) {
using P=pair<ll,ll>;
vector<P> pos,used;
rep(i,0,n){
if(r[i]>c[i])swap(r[i],c[i]);
c[i]++;
pos.push_back({r[i],c[i]});
}
sort(ALL(pos),[](P& a,P& b){
if(a.first==b.first)return a.second>b.second;
else return a.first<b.first;
});
ll mx=-1;
rep(i,0,n){
if(!chmax(mx,pos[i].second))continue;
used.push_back(pos[i]);
}
n=used.size();
r.clear();
c.clear();
for(auto& [x,y]:used){
r.push_back(x);
c.push_back(y);
}
auto get=[&](ll pena)->P{
vector<ll> ps,dp(n+10,INF),dp2(n+10,INF);
dp[0]=dp2[0]=0;
rep(i,0,n)ps.push_back(c[i]);
CHT cht(ps);
rep(i,0,n){
ll b=dp[i]+ll(r[i])*r[i];
if(i and c[i-1]>r[i])b-=ll(c[i-1]-r[i])*(c[i-1]-r[i]);
cht.add(-2LL*r[i],b);
auto [v,a]=cht.query(i);
int pre=lower_bound(ALL(r),-a/2)-r.begin();
if(chmin(dp[i+1],v+ll(c[i])*c[i]+pena)){
chmin(dp2[i+1],dp2[pre]+1);
}
}
return {dp[n],dp2[n]};
};
if(k>=n){
return get(0).first;
}
ll lb=-1,rb=ll(m)*m+10;
while(rb-lb>1){
ll mid=(lb+rb)>>1;
if(get(mid).second<=k)rb=mid;
else lb=mid;
}
return get(rb).first-rb*k;
}
/*
int main() {
int n, m, k;
assert(3 == scanf("%d %d %d", &n, &m, &k));
std::vector<int> 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;
}
//*/
# | 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... |