이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include"aliens.h"
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
struct Line{
ll a,b;
int min_pics,max_pics;
};
ll eval(Line l,ll x){
return l.a*x+l.b;
}
struct CHT{
int l,r;
CHT*ch1,*ch2;
Line cl;
CHT(int l,int r):l(l),r(r),ch1(nullptr),ch2(nullptr){
cl.a=0;
cl.b=1e18;
}
void add(Line line){
int mid=(l+r)/2;
if(eval(line,mid)<eval(cl,mid))
swap(line,cl);
if(eval(line,mid)==eval(cl,mid)&&eval(line,l)==eval(cl,l)){
cl.min_pics=min(cl.min_pics,line.min_pics);
cl.max_pics=max(cl.max_pics,line.max_pics);
return;
}
if(l<r-1){
if(eval(line,l)<eval(cl,l)){
if(ch1==nullptr)
ch1=new CHT(l,mid);
ch1->add(line);
}
if(eval(line,r)<eval(cl,r)){
if(ch2==nullptr)
ch2=new CHT(mid,r);
ch2->add(line);
}
}
}
pair<ll,pair<int,int>>get(ll x){
int mid=(l+r)/2;
pair<ll,pair<int,int>>res={eval(cl,x),{cl.min_pics,cl.max_pics}};
if(x>=mid&&ch2){
auto res2=ch2->get(x);
if(res2.first<res.first){
res=res2;
}else if(res2.first==res.first){
res.second.first=min(res.second.first,res2.second.first);
res.second.second=max(res.second.second,res2.second.second);
}
}
if(x<mid&&ch1){
auto res2=ch1->get(x);
if(res2.first<res.first){
res=res2;
}else if(res2.first==res.first){
res.second.first=min(res.second.first,res2.second.first);
res.second.second=max(res.second.second,res2.second.second);
}
}
return res;
}
};
int n;
vector<ll>l,r;
ll sq(ll x){
return x*x;
}
bool cmp(pair<int,int>a,pair<int,int>b){
if(a.first==b.first)
return a.second>b.second;
return a.first<b.first;
}
// (points, num of pictures) if pictures are unlimited but have a specific cost
// num of picures will be minimal and maximal while still having optimal points
pair<ll,pair<int,int>>get(ll cost){
vector<ll>dp(n+1); // optimum for first i intervals
vector<pair<int,int>>num_pic(n+1);
CHT cht(0,1<<20);
for(int i=1;i<=n;i++){
Line line;
line.b=l[i-1]*l[i-1]+dp[i-1]+cost;
if(i!=1)
line.b-=sq(max(0LL,r[i-2]-l[i-1]));
line.a=-2*l[i-1];
line.min_pics=num_pic[i-1].first+1;
line.max_pics=num_pic[i-1].second+1;
cht.add(line);
auto res=cht.get(r[i-1]);
res.first+=r[i-1]*r[i-1];
dp[i]=res.first;
num_pic[i]=res.second;
//cout<<"res1 "<<dp[i]<<" "<<num_pic[i].first<<" "<<num_pic[i].second<<endl;
/*dp[i]=1e18;
for(int j=0;j<i;j++){
ll curr=r[i-1]*r[i-1]-2*l[j]*r[i-1]+l[j]*l[j];
curr+=dp[j];
curr+=cost;
if(j)
curr-=sq(max(0LL,r[j-1]-l[j]));
if(curr<dp[i]){
dp[i]=curr;
num_pic[i].first=num_pic[j].first+1;
num_pic[i].second=num_pic[j].second+1;
}else if(curr==dp[i]){
num_pic[i].first=min(num_pic[i].first,num_pic[j].first+1);
num_pic[i].second=max(num_pic[i].second,num_pic[j].second+1);
}
}*/
//cout<<"res2 "<<dp[i]<<" "<<num_pic[i].first<<" "<<num_pic[i].second<<endl;
//cout<<"\n";
}
return{dp[n],num_pic[n]};
}
ll take_photos(int N,int m,int k,vector<int>R,vector<int>C){
n=N;
vector<pair<int,int>>intervals_sorted;
for(int i=0;i<n;i++){
if(R[i]>C[i])
swap(R[i],C[i]);
intervals_sorted.emplace_back(R[i],C[i]);
}
sort(intervals_sorted.begin(),intervals_sorted.end(),cmp);
int right_done=-1;
for(auto i:intervals_sorted){
if(i.second>right_done){
l.push_back(i.first);
r.push_back(i.second+1);
right_done=i.second;
}
}
n=(int)l.size();
k=min(n,k);
ll l=0,r=(ll)m*m+1;
ll opt;
while(true){
ll mid=(l+r)/2;
auto res=get(mid);
//cout<<mid<<": "<<res.first<<" "<<res.second.first<<" "<<res.second.second<<endl;
if(res.second.first>k)
l=mid;
if(res.second.second<k)
r=mid;
if(res.second.first<=k&&k<=res.second.second){
opt=mid;
break;
}
}
//cout<<"opt "<<opt<<"\n";
auto res=get(opt);
ll ret=res.first-opt*k;
return ret;
}
# | 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... |