結果
| 問題 |
No.913 木の燃やし方
|
| コンテスト | |
| ユーザー |
sigma425
|
| 提出日時 | 2019-10-18 22:28:33 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 324 ms / 3,000 ms |
| コード長 | 2,766 bytes |
| コンパイル時間 | 2,397 ms |
| コンパイル使用メモリ | 202,384 KB |
| 最終ジャッジ日時 | 2025-01-07 23:09:32 |
|
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 34 |
ソースコード
#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define rep1(i,n) for(int i=1;i<=(int)(n);i++)
#define all(c) c.begin(),c.end()
#define pb push_back
#define fs first
#define sc second
#define chmin(x,y) x=min(x,y)
#define chmax(x,y) x=max(x,y)
using namespace std;
template<class S,class T> ostream& operator<<(ostream& o,const pair<S,T> &p){
return o<<"("<<p.fs<<","<<p.sc<<")";
}
template<class T> ostream& operator<<(ostream& o,const vector<T> &vc){
o<<"{";
for(const T& v:vc) o<<v<<",";
o<<"}";
return o;
}
using ll = long long;
template<class T> using V = vector<T>;
template<class T> using VV = vector<vector<T>>;
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n-1); }
#ifdef LOCAL
#define show(x) cerr << "LINE" << __LINE__ << " : " << #x << " = " << (x) << endl
#else
#define show(x) true
#endif
struct CHT{
using D = ll;
typedef pair<D,D> P;
vector<P> deq;
int s,sd,t;
CHT():s(0),sd(0),t(0){}
void add(D a,D b){ //add ax+b a:(広義)単調減少!!!
P p(a,b);
while(s+1<t&&check(deq[t-2],deq[t-1],p)) t--;
if(t == (int)deq.size()) deq.pb(p);
deq[t++]=p;
}
D incr_query(D x){ //x:単調増加の時,これを繰り返し呼ぶ(間にaddが挟まるのはOK)
while(s+1<t&&f(deq[s],x)>=f(deq[s+1],x)) s++;
return f(deq[s],x);
}
D decr_query(D x){ //x:単調減少の時,これを繰り返し呼ぶ(間にaddが挟まるのはOK)
if(sd>=t) sd=t-1;
while(sd+1<t&&f(deq[sd],x)>=f(deq[sd+1],x)) sd++;
while(sd>0&&f(deq[sd],x)<f(deq[sd-1],x)) sd--;
return f(deq[sd],x);
}
D query(D x){
int lb=s-1,ub=t-1;
while(ub-lb>1){
int m=(lb+ub)/2;
if(isright(deq[m],deq[m+1],x)) lb=m;
else ub=m;
}
return f(deq[ub],x);
}
bool isright(P& a,P& b,D x){
return f(a,x)>=f(b,x);
}
bool check(P& a,P& b,P& c){
return (b.fs-a.fs)*(c.sc-b.sc)>=(b.sc-a.sc)*(c.fs-b.fs);
}
D f(P &p,int x){
return p.fs*x+p.sc;
}
};
int main(){
cin.tie(0);
ios::sync_with_stdio(false); //DON'T USE scanf/printf/puts !!
cout << fixed << setprecision(20);
int N; cin >> N;
V<ll> A(N); rep(i,N) cin >> A[i];
V<ll> S(N+1); rep(i,N) S[i+1] = S[i] + A[i];
const ll inf = 1e18;
V<ll> ans(N,inf);
function<void(int,int)> f = [&](int L,int R){
if(L == R) return;
int m = (L+R)/2;
//L<=j<=m<=p<i<=R
{
CHT cht;
for(ll j=L;j<=m;j++) cht.add(-j*2,j*j-S[j]);
ll mn = inf;
for(ll i=R;i>=m+1;i--){
ll val=cht.query(i) + i*i + S[i];
chmin(mn,val);
chmin(ans[i-1],mn);
}
}
//L<=j<=p<m<i<=R
{
CHT cht;
for(ll i=m+1;i<=R;i++) cht.add(-i*2,i*i+S[i]);
ll mn = inf;
for(ll j=L;j<m;j++){
ll val=cht.query(j) + j*j - S[j];
chmin(mn,val);
chmin(ans[j],mn);
}
}
f(L,m);
f(m+1,R);
};
f(0,N);
rep(i,N) cout << ans[i] << '\n';
}
sigma425