제출 #404754

#제출 시각아이디문제언어결과실행 시간메모리
404754drogskolAliens (IOI16_aliens)C++17
0 / 100
1 ms204 KiB
#include <bits/stdc++.h> using namespace std; #define REP(i,n) for(int i=0;i<(n);i++) #define ALL(v) v.begin(),v.end() //base:[Convex-Hull Trick - sataniC++](http://satanic0258.hatenablog.com/entry/2016/08/16/181331#fn-534591c8) //追加する直線の傾きは単調(最小値なら傾きは単調減少、最大値なら傾きは単調増加) template<typename T> struct ConvecHullTrick { typedef pair<T,T> Line; vector<Line> lines; //直線(傾き,切片) bool isMonotonicX; //最小値(最大値)を求めるxが単調であるか function<bool(T l, T r)> comp; //最小/最大を判断する関数 //flag:クエリは単調? compFunc:求めるのは最大値? ConvecHullTrick(bool flagX=0,bool compFunc=0):isMonotonicX(flagX){ if(compFunc)comp=[](T l,T r){return l<=r;}; else comp=[](T l,T r){return l>=r;}; }; //直線l1,l2,l3のうちl2が不必要であるかどうか bool check(Line l1,Line l2,Line l3){ if(l1<l3)swap(l1,l3); T a1=l1.first,a2=l2.first,a3=l3.first,b1=l1.second,b2=l2.second,b3=l3.second; return (b3-b2)*(a2-a1)>=(b2-b1)*(a3-a2); } //直線y=ax+bを追加する 単調性から付け足すのは一番後ろで、不必要なやつが消えるまで一番後ろを消したら付け足す void add(T a, T b) { Line line(a,b); while(lines.size()>=2&&check(*(lines.end()-2),lines.back(),line))lines.pop_back(); lines.emplace_back(line); } //linesのi番目の直線のxでの値 T f(int i,T x) { return lines[i].first*x+lines[i].second; } //特定のlineのxでの値 T f(Line line,T x) { return line.first*x+line.second; } //直線群の中でxの時に最小(最大)となる値を返す T get(T x){ assert(lines.size()); if(isMonotonicX){//最小値(最大値)クエリにおけるxが単調(昇順) static int head=0; while(lines.size()-head>=2&&comp(f(head,x),f(head+1,x)))head++; return f(head,x); } else{ int low=-1,high=lines.size()-1; while(high-low>1){ int mid=(high+low)>>1; if(comp(f(mid,x),f(mid+1,x)))low=mid; else high=mid; } return f(high,x); } } }; using ll=long long; ll shortest(int n,vector<int> &r,vector<int> &c,ll t){//t:ラグランジュ双対のパラメータ ConvecHullTrick<ll> CHT(1,0); REP(i,n){ ll D=(i?CHT.get(c[i-1]):0LL);//[0,i)を撮る最小コスト CHT.add(-2*r[i],r[i]*r[i]+t+D); } return CHT.get(c[n-1]); } ll take_photos(int n,int m,int k,vector<int> r,vector<int> c){ REP(i,n)if(r[i]>c[i])swap(r[i],c[i]); ll lt=-3e10,rt=3e10;//tの下限,上限 while(rt-lt>2){ ll t1=lt+(rt-lt)/3,t2=lt+(rt-lt)*2/3; if(shortest(n,r,c,t1)<shortest(n,r,c,t2))rt=t2; else lt=t1; } ll t1=lt+(rt-lt)/3,t2=lt+(rt-lt)*2/3; return min(shortest(n,r,c,t1),shortest(n,r,c,t2)); }
#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...