Submission #104762

#TimeUsernameProblemLanguageResultExecution timeMemory
104762minson123Aliens (IOI16_aliens)C++11
0 / 100
5 ms2816 KiB
#include "aliens.h" #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<ll,int> pli; const int maxn=100010; struct Section{ int l,r; Section(int _l=0,int _r=0):l(_l),r(_r){} inline bool operator<(const Section& rhs) const{ return l!=rhs.l?l<rhs.l:r>rhs.r; } inline bool operator==(const Section& rhs) const{ return l==rhs.l && r==rhs.r; } }; struct Line{ ll a,b; int idx; Line(ll _a=0,ll _b=0,int _idx=0):a(_a),b(_b),idx(_idx){} } dq[maxn]; inline bool check(Line l,Line l2,Line l3){ ll a1=l.a,b1=l.b; ll a2=l2.a,b2=l2.b; ll a3=l3.a,b3=l3.b; return (a2-a3)*(b3-b1)>=(b3-b2)*(a1-a3); } inline ll get_val(ll x,Line l){ return x*l.a+l.b; } pli dp[maxn]; vector<Section> sec,tmp; set<int> dic; bool ban[maxn]; inline int calc_dp(ll ext){ dp[0]=pli(0,0); int head=0,rear=0; dq[rear++]=Line(-2ll*sec[0].l,(ll)sec[0].l*sec[0].l,0); for(int i=1;i<=(int)sec.size();i++){ while(head+1<rear && get_val(sec[i-1].r+1,dq[head])>=get_val(sec[i-1].r+1,dq[head+1])) head++; dp[i].first=get_val(sec[i-1].r+1,dq[head])+(ll)(sec[i-1].r+1)*(sec[i-1].r+1)+ext; dp[i].second=dp[dq[head].idx].second+1; if(i<(int)sec.size()){ Line ln=Line(-2ll*sec[i].l,(ll)sec[i].l*sec[i].l-max(0ll,(ll)(sec[i-1].r-sec[i].l+1)*(sec[i-1].r-sec[i].l+1))+dp[i].first); while(head+1<rear && check(dq[rear-2],dq[rear-1],ln)) rear--; dq[rear++]=ln; } } return dp[(int)sec.size()].second; } long long take_photos(int n, int m, int k, std::vector<int> r, std::vector<int> c) { for(int i=0;i<n;i++){ Section s=Section(r[i],c[i]); if(s.l>s.r) swap(s.l,s.r); sec.push_back(s); } sort(sec.begin(),sec.end()); sec.erase(unique(sec.begin(),sec.end()),sec.end()); for(int i=0;i<(int)sec.size();i++){ set<int>::iterator it=dic.lower_bound(sec[i].r); if(it!=dic.end()) ban[i]=true; dic.insert(sec[i].r); } for(int i=0;i<(int)sec.size();i++) if(!ban[i]) tmp.push_back(sec[i]); sec=tmp; ll L=0,R=20000000000000ll; while(L!=R){ ll mid=(L+R)>>1; if(calc_dp(mid)<=k) R=mid; else L=mid+1; } calc_dp(R); return dp[(int)sec.size()].first-R*k; }
#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...