結果
問題 | No.705 ゴミ拾い Hard |
ユーザー |
![]() |
提出日時 | 2018-06-20 01:47:32 |
言語 | C++11 (gcc 13.3.0) |
結果 |
AC
|
実行時間 | 121 ms / 1,500 ms |
コード長 | 2,130 bytes |
コンパイル時間 | 1,502 ms |
コンパイル使用メモリ | 168,020 KB |
実行使用メモリ | 12,880 KB |
最終ジャッジ日時 | 2024-06-30 17:22:50 |
合計ジャッジ時間 | 5,646 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 40 |
ソースコード
#include <bits/stdc++.h> using namespace std; typedef signed long long ll; #undef _P #define _P(...) (void)printf(__VA_ARGS__) #define FOR(x,to) for(x=0;x<(to);x++) #define FORR(x,arr) for(auto& x:arr) #define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++) #define ALL(a) (a.begin()),(a.end()) #define ZERO(a) memset(a,0,sizeof(a)) #define MINUS(a) memset(a,0xff,sizeof(a)) //------------------------------------------------------- int N; ll A[303030]; ll X[303030]; ll Y[303030]; ll D[303030]; ll dist(int a,int b) { ll x=abs(A[b]-X[a]); ll y=abs(Y[a]); return x*x*x+y*y*y; } ll cost(int prev,int now) { return D[prev]+dist(prev+1,now); } int hoge(int L,int R) { // cost(L,m) >= cost(R,m)となる最小のm int TL=1, TR=N+1; while(TR-TL>1) { int TM=(TR+TL)/2; ((cost(L,TM) >= cost(R,TM))?TR:TL)=TM; } return TR; } void solve() { int i,j,k,l,r,x,y; string s; cin>>N; FOR(i,N) cin>>A[i+1]; FOR(i,N) cin>>X[i+1]; FOR(i,N) cin>>Y[i+1]; deque<pair<int,int>> Q; Q.push_back({0,1}); for(int now=1;now<=N;now++) { int pre=Q.back().first; //cout<<now<<" "<<pre<<" "; //FORR(q,Q) cout<<q.first<<":"<<q.second<<" "; if(cost(pre,now) >= cost(now-1,now)) { //最新の値が最適 D[now]=cost(now-1,now); Q.clear(); Q.push_back({now-1,now+1}); } else { //現状の最適値 D[now]=cost(pre,now); //最新のケースの方がいい場合、それを先頭に追加していく while(cost(now-1,Q[0].second)<=cost(Q[0].first,Q[0].second)) Q.pop_front(); //これまでの範囲でコストが反転する場所 int h=hoge(Q[0].first,now-1); //hからコストが反転する if(h<=N) { Q.push_front({now-1,h}); } //反転開始するなら末尾を葉ずつ if(Q.size()>=2 && Q[Q.size()-2].second==now+1) Q.pop_back(); else Q.back().second++; } //cout<<D[now]<<endl; } cout<<D[N]<<endl; } int main(int argc,char** argv){ string s;int i; if(argc==1) ios::sync_with_stdio(false), cin.tie(0); FOR(i,argc-1) s+=argv[i+1],s+='\n'; FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin); cout.tie(0); solve(); return 0; }