QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#735538 | #9127. Optimal Train Operation | ucup-team134# | WA | 2ms | 12220kb | C++14 | 3.6kb | 2024-11-11 20:34:49 | 2024-11-11 20:34:49 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
const ll inf=9e18;
const int N=500050;
int a[N],c[N];
ll dp[N],bdp[N];
struct Line{
ll k,n;
Line(){}
Line(ll a,ll b):k(a),n(b){}
ll Get(ll x){
return x*k+n;
}
};
ll sec(Line a,Line b){
ll dk=a.k-b.k;
ll dn=b.n-a.n;
if(dk<0)dk=-dk,dn=-dn;
if(dn<0)return dn/dk;
else return (dn+dk-1)/dk;
}
vector<int> hullIds;
vector<Line> hull;
void ExtendHull(int idx,Line line){
int sz=hull.size();
while(sz>=2 && sec(hull[sz-2],hull[sz-1])>=sec(hull[sz-1],line)){
hull.pop_back();
hullIds.pop_back();
sz--;
}
hull.pb(line);
hullIds.pb(idx);
}
int FindBot(int l,int r){
int top=(int)hull.size()-1;
int bot=0;
int ans=(int)hull.size()-1;
while(top>=bot){
int mid=top+bot>>1;
if(hullIds[mid]>=l){
ans=mid;
top=mid-1;
}else{
bot=mid+1;
}
}
return ans;
}
Line GetLine(int l,int r,ll x){
int top=(int)hull.size()-2;
int bot=FindBot(l,r);
int best=top+1;
while(top>=bot){
int mid=top+bot>>1;
if(hull[mid].Get(x)<hull[mid+1].Get(x)){
best=mid;
top=mid-1;
}else{
bot=mid+1;
}
}
return Line(x,hull[best].Get(x));
}
const int L=20;
const int M=N*L;
int ls[M],rs[M],tsz;
Line line[M];
bool has[M];
void Copy(int&c){
++tsz;
ls[tsz]=ls[c];
rs[tsz]=rs[c];
line[tsz]=line[c];
has[tsz]=has[c];
c=tsz;
}
void AddLine(int &c,int ss,int se,Line l){
Copy(c);
if(!has[c]){
line[c]=l;
has[c]=true;
return;
}
ll A=line[c].Get(ss);
ll B=l.Get(ss);
ll C=line[c].Get(se);
ll D=l.Get(se);
if(A<=B && C<=D)return;
if(A>=B && C>=D){
line[c]=l;
return;
}
if(A>B)swap(l,line[c]);
int mid=ss+se>>1;
if(line[c].Get(mid)<=l.Get(mid))AddLine(rs[c],mid+1,se,l);
else{
swap(l,line[c]);
AddLine(ls[c],ss,mid,l);
}
}
ll Get(int c,int ss,int se,int qi){
if(!has[c])return inf;
ll ans=line[c].Get(qi);
if(ss==se)return ans;
int mid=ss+se>>1;
if(qi<=mid)ans=min(ans,Get(ls[c],ss,mid,qi));
else ans=min(ans,Get(rs[c],mid+1,se,qi));
return ans;
}
int main(){
int n;
scanf("%i",&n);
for(int i=1;i<=n;i++){
scanf("%i",&c[i]);
}
for(int i=2;i<=n;i++){
scanf("%i",&a[i]);
}
n++;
dp[1]=0;
bdp[1]=0;
vector<int> roots;
vector<int> stk;
stk.push_back(1);
roots.push_back(0);
ExtendHull(1,Line(-1,0));
for(int i=2;i<=n;i++){
while(stk.size()>1 && c[stk.back()-1]<=c[i-1]){
stk.pop_back();
roots.pop_back();
}
int newRoot=roots.back();
Line line=GetLine(stk.back(),i-1,c[i-1]);
//printf("AddLine (%i * x + %i) [%i, %i]\n",line.k,line.n,stk.back(),i-1);
AddLine(newRoot,1,n,line);
stk.pb(i);
roots.pb(newRoot);
dp[i]=Get(newRoot,1,n,i)+a[i];
ExtendHull(i,Line(-i,dp[i]));
// Brute
/*int mx=0;
bdp[i]=inf;
for(int j=i-1;j>=1;j--){
mx=max(mx,c[j]);
bdp[i]=min(bdp[i],bdp[j]+(ll)mx*(i-j)+a[i]);
}
printf("(dp:%lld bdp:%lld)\n",dp[i],bdp[i]);
for(int j=0;j<hull.size();j++){
printf("%i (%i * x + %i)\n",hullIds[j],hull[j].k,hull[j].n);
}*/
}
printf("%lld\n",dp[n]);
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 2ms
memory: 12220kb
input:
4 3 1 4 1 5 9 2
output:
15
result:
ok "15"
Test #2:
score: 0
Accepted
time: 0ms
memory: 11912kb
input:
9 28 35 19 27 84 98 78 79 60 40 35 54 63 72 71 27 94
output:
682
result:
ok "682"
Test #3:
score: 0
Accepted
time: 0ms
memory: 12220kb
input:
7 476190629 262703497 211047202 971407775 628894325 731963982 822804784 877914575 602436426 24979445 861648772 623690081 433933447
output:
5339182432
result:
ok "5339182432"
Test #4:
score: -100
Wrong Answer
time: 1ms
memory: 11908kb
input:
8 910286918 802329211 404539679 303238506 317063340 492686568 773361868 125660016 430302156 982631932 161735902 880895728 923078537 707723857 189330739
output:
6311516364
result:
wrong answer 1st words differ - expected: '6166732840', found: '6311516364'