제출 #899464

#제출 시각아이디문제언어결과실행 시간메모리
899464JakobZorzAliens (IOI16_aliens)C++17
25 / 100
5 ms604 KiB
#include"aliens.h"
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef pair<ll,ll>Line;
 
ll eval(Line l,ll x){
    return l.first*x+l.second;
}
 
struct CHT{
    int l,r;
    CHT*ch1,*ch2;
    Line cl;
    
    CHT(int l,int r):l(l),r(r),ch1(nullptr),ch2(nullptr){
        cl={0,1e18};
    }
    
    void add(Line line){
        int mid=(l+r)/2;
        if(eval(line,mid)<eval(cl,mid))
            swap(line,cl);
        
        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);
            }
        }
    }
    
    ll get(ll x){
        int mid=(l+r)/2;
        ll res=eval(cl,x);
        //cout<<"res = "<<res<<"\n";
        //cout<<"line = "<<cl.first<<" "<<cl.second<<"\n";
        if(x>=mid&&ch2)
            res=min(res,ch2->get(x));
        if(x<mid&&ch1)
            res=min(res,ch1->get(x));
        //cout<<"res2 = "<<res<<"\n";
        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(int cost){
    vector<ll>dp(n+1); // optimum for first i intervals
    vector<pair<int,int>>num_pic(n+1);
    for(int i=1;i<=n;i++){
        dp[i]=1e18;
        for(int j=0;j<i;j++){
            ll curr=sq(r[i-1]-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);
            }
        }
    }
    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);
    
    int l=0,r=m*m;
    int opt;
    while(true){
        int 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;
        }
        if(l>=r-1){
            return -1;
        }
    }
    
    //cout<<"opt "<<opt<<"\n";
    auto res=get(opt);
    ll ret=res.first-opt*k;
    
    return ret;
}
#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...