Submission #1241493

#TimeUsernameProblemLanguageResultExecution timeMemory
1241493noyancanturkOvertaking (IOI23_overtaking)C++20
0 / 100
1 ms836 KiB
#include "overtaking.h"

#include<bits/stdc++.h>
using namespace std;

#define pb push_back

const int lim=1100;

using mint=long long;
using pii=pair<mint,mint>;

mint dp[lim][lim],ansdp[lim][lim];

int n,m,x;

vector<mint>t;
vector<int>w,s;
mint c[lim];
double aa[lim];
int p[lim][lim];
mint reach[lim][lim];

int calc(int i,mint y){
  int l=0,r=n-1,res=-1;
  while(l<=r){
    int mid=l+r>>1;
    if(y==dp[i][p[i][mid]]){
      if(w[p[i][mid]]<x){
        l=mid+1;
        res=mid;
      }else{
        r=mid-1;
      }
    }else if(dp[i][p[i][mid]]<y){
      l=mid+1;
      res=mid;
    }else{
      r=mid-1;
    }
  }
  return res;
}

void init(int L,int N,vector<mint>T,vector<int>W,int X,int M,vector<int> S)
{   
  n=N,m=M,x=X;
  t=T,w=W,s=S;
  for(int i=0;i<n;i++){
    if(w[i]<=x){
      swap(w[i],w.back());
      swap(t[i],t.back());
      w.pop_back();
      t.pop_back();
      i--;
      n--;
    }
  }
  for(int i=0;i<n;i++){
    dp[0][i]=t[i];
  }
  for(int i=0;i+1<m;i++){
    iota(p[i],p[i]+n,0);
    sort(p[i],p[i]+n,[&](int i1,int i2)->bool {
      if(dp[i][i1]^dp[i][i2])return dp[i][i1]<dp[i][i2];
      return w[i1]<w[i2];
    });
    for(int j=0;j<n;j++){
      dp[i+1][j]=dp[i][j]+1ll*w[j]*(s[i+1]-s[i]);
    }
    for(int j=1;j<n;j++){
      dp[i+1][p[i][j]]=max(dp[i+1][p[i][j]],dp[i+1][p[i][j-1]]);
    }
  }
  for(int i=0;i<n;i++){
    ansdp[m-1][i]=dp[m-1][i];
    c[i]=w[i]-x;
    aa[i]=1./c[i];
  }
  for(int i=m-2;0<=i;i--){
    vector<int>inds;
    for(int j=0;j<n;j++){
      if(j+1<n&&dp[i][p[i][j]]==dp[i][p[i][j+1]])continue;
      // cerr<<"calc "<<i<<' '<<p[i][j]<<'\n';
      ansdp[i][p[i][j]]=dp[i][p[i][j]]+1ll*x*(s[m-1]-s[i]);
      if(inds.size()){
        // cerr<<dp[i][p[i][j]]-dp[i][inds.back()]<<'\n';
        mint colloc=s[i]+(dp[i][p[i][j]]-dp[i][inds.back()]+c[inds.back()]-1)/c[inds.back()];
        int willcol=lower_bound(s.begin(),s.end(),colloc)-s.begin();
        if(willcol<m){
          // cerr<<"pull "<<willcol<<' '<<inds.back()<<'\n';
          ansdp[i][p[i][j]]=ansdp[willcol][inds.back()];
        }
      }
      int sz;
      while((sz=inds.size())&&w[sz-1]<w[p[i][j]])inds.pop_back();
      while(1<(sz=inds.size())){
        double a1=-aa[p[i][j]];
        double a2=-aa[inds[sz-1]];
        double a3=-aa[inds[sz-2]];
        double b1=aa[p[i][j]]*dp[i][p[i][j]];
        double b2=aa[inds[sz-1]]*dp[i][inds[sz-1]];
        double b3=aa[inds[sz-2]]*dp[i][inds[sz-2]];
        if((a2-a3)/(b3-b2)<(a1-a2)/(b2-b1)){
          inds.pop_back();
        }else break;
      }
      inds.pb(p[i][j]);
    }
  }
  for(int i=0;i<m;i++){
    reach[p[0][0]][i]=dp[i][p[0][0]];
  }
  for(int i=1;i<n;i++){
    for(int j=0;j<m;j++){
      reach[p[0][i]][j]=max(reach[p[0][i-1]][j],dp[j][p[0][i]]);
    }
  }
  // for(int i=0;i<n;i++){
  //   for(int j=0;j<m;j++){
  //     cerr<<dp[j][i]<<' ';
  //   }cerr<<'\n';
  // }cerr<<'\n';
  // for(int i=0;i<m;i++){
  //   for(int j=0;j<n;j++){
  //     cerr<<ansdp[i][j]<<' ';
  //   }cerr<<'\n';
  // }cerr<<'\n';
  return;
}

mint arrival_time(mint y)
{
  int place=calc(0,y);
  if(place==-1){
    return y+1ll*x*s[m-1];
  }
  int l=0,r=m-1,ans=m;
  while(l<=r){
    int mid=l+r>>1;
    if(y+1ll*x*s[mid]<reach[place][mid]){
      ans=mid;
      r=mid-1;
    }else{
      l=mid+1;
    }
  }
  if(ans==m){
    return y+1ll*x*s[m-1];
  }
  mint globans=reach[place][ans];
  // cerr<<ans<<' '<<globans<<'\n';
  for(int i=n-1;0<=i;i--){
    if(dp[ans][p[ans][i]]==globans){
      // cerr<<"access "<<ans<<' '<<p[ans][i]<<'\n';
      return ansdp[ans][p[ans][i]];
    }
  }
  assert(0);
}
#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...