結果
問題 | No.704 ゴミ拾い Medium |
ユーザー |
![]() |
提出日時 | 2019-06-28 10:56:43 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 622 ms / 1,500 ms |
コード長 | 3,089 bytes |
コンパイル時間 | 1,692 ms |
コンパイル使用メモリ | 139,176 KB |
最終ジャッジ日時 | 2025-01-07 05:13:24 |
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 44 |
ソースコード
#include<iomanip>#include<limits>#include<thread>#include<utility>#include<iostream>#include<string>#include<algorithm>#include<set>#include<map>#include<vector>#include<stack>#include<queue>#include<cmath>#include<numeric>#include<cassert>#include<random>#include<chrono>#include<unordered_set>#include<unordered_map>#include<fstream>#include<list>#include<functional>#include<bitset>#include<complex>#include<tuple>using namespace std;typedef unsigned long long int ull;typedef long long int ll;typedef pair<ll,ll> pll;typedef long double D;typedef complex<D> P;#define F first#define S secondconst ll E=1e18+7;const ll MOD=1000000007;template<typename T,typename U>istream & operator >> (istream &i,pair<T,U> &A){i>>A.F>>A.S; return i;}template<typename T>istream & operator >> (istream &i,vector<T> &A){for(auto &I:A){i>>I;} return i;}template<typename T,typename U>ostream & operator << (ostream &o,pair<T,U> &A){o<<A.F<<" "<<A.S; return o;}template<typename T>ostream & operator << (ostream &o,vector<T> &A){ll i=A.size(); for(auto &I:A){o<<I<<(--i?" ":"");} return o;}template<typename T>vector<T> & cset(vector<T> &A,T e=T()){for(auto &I:A){I=e;} return A;}const int SIZE=300500;namespace Monotone_Minima{vector<int> am(SIZE);function<ll(int,int)> fnc;//argmin(cul(i,*))<=argmin(cul(j,*)) for(i<j)//を満たすn行m列の行列で、各行の最小値を求め、そのindexを返す。template<typename T>void argmin(int n,int m){for(int i=0;i<n;i++){am[i]=-1;}int i=2;while(i<n){i<<=1;}while(i>>=1){for(int j=0;j<n;j+=i){if(am[j]!=-1){continue;}int l=(j-i>=0 && am[j-i]!=-1?am[j-i]:0),r=(j+i<n && am[j+i]!=-1?am[j+i]+1:m);T a=fnc(j,l);am[j]=l;for(int k=l+1;k<r;k++){if(fnc(j,k)<a){a=fnc(j,k);am[j]=k;}}}}}//f(i,k)+f(j,l)<=f(i,l)+f(j,k) for(i<=j,k<=l)//を満たすn行n列の行列Aに対して、//dp[i]=min_{j<i} dp[j]+A_{i,j}//を求める。template<typename T>vector<T> divide_and_conquer(function<T(int,int)> cul,int n,T e=T()){vector<T> ret(n,e);for(int i=1;i<n;i++){ret[i]=ret[0]+cul(i,0);}for(int i=1;i<n;i++){int j=i&(-i);int k=i-j;fnc=[&](int a,int b){return ret[k+b]+cul(i+a,k+b);};argmin<T>(min(j,n-i),j);for(int s=0;s<j && i+s<n;s++){T a=fnc(s,am[s]);if(a<ret[i+s]){ret[i+s]=a;}}}return ret;}}using namespace Monotone_Minima;int main(){ll n;cin>>n;vector<ll> A(n),X(n),Y(n);cin>>A>>X>>Y;function<ll(int,int)> cul=[&](int i,int j){i--; return i<j?1e15:abs(A[i]-X[j])+abs(Y[j]);};vector<ll> ans=divide_and_conquer<ll>(cul,n+1,0);cout<<ans.back()<<endl;return 0;}