# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
124761 | arthurconmy | Salesman (IOI09_salesman) | C++14 | 529 ms | 27640 KiB |
This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
// check ctrl+v :^)
/* Arthur Conmy IOI template - minimal! */
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#include <map>
#include <queue>
#include <bitset>
#include <random>
#include <stack>
#include <deque>
#include <chrono>
using namespace std;
using ll = long long;
using vi = vector<int>;
using pii = pair<int,int>;
#define pb push_back
#define ff first
#define ss second
#define REP(i,a,b) \
for(int i = int(a); i<=int(b); i++)
const ll NEG_INF = -1e18;
ll n,u,d,s;
tuple<int,int,int> fairs[500001]; // keep it int for space reasons
ll st[2][1048576]; // first is up, second is down monkaS for memory again!
ll dp[500001];
ll query(int l, int r, int tree)
{
ll ans=NEG_INF;
l+=524288;
r+=524288;
l--;
r--;
while(l<=r) // we know there's inequality in the case of the query RMQ(i,i)
{
if(l%2 == 1)
{
ans=max(ans,st[tree][l++]);
}
if(r%2 == 0)
{
ans=max(ans,st[tree][r--]);
}
l/=2;
r/=2;
}
return ans;
}
void update(int pos, ll new_val, int tree)
{
pos+=524288;
pos--;
st[tree][pos]=max(st[tree][pos],new_val);
//cout << st[tree][pos] << endl;
pos/=2;
while(pos>0)
{
st[tree][pos] = max(st[tree][pos+pos],st[tree][pos+pos+1]);
pos/=2;
}
}
int main()
{
#ifdef ARTHUR_LOCAL
ifstream cin("input.txt");
#endif
REP(i,0,1)
{
REP(j,0,1048575)
{
st[i][j]=NEG_INF;
}
}
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin>>n>>u>>d>>s;
// vector<tuple<int,int,int>> fairs;
REP(i,1,n)
{
int t,l,m;
cin>>t>>l>>m;
fairs[i]={t,l,m};
}
sort(fairs+1,fairs+n+1);
REP(i,1,n)
{
// cout << get<0>(fairs[i]) << " " << get<1>(fairs[i]) << " " << get<2>(fairs[i]) << endl;
ll pos_cur = ll(get<1>(fairs[i]));
ll prof_cur = ll(get<2>(fairs[i]));
dp[i]=prof_cur;
if(pos_cur>=s) dp[i]-=d*(pos_cur-s); // downstream
else dp[i]-=u*(s-pos_cur); // upstream. Yes this is the other way around to below
// UPSTREAM QUERY
dp[i]=max(dp[i],prof_cur + u*pos_cur + query(pos_cur,500000,0));
// DOWNSTREAM QUERY
dp[i]=max(dp[i],prof_cur - d*pos_cur + query(1,pos_cur,1));
// UPSTREAM UPDATE
update(int(pos_cur),dp[i]-u*pos_cur,0); // do we update with the DP value? Probably
// if(i==1) cout << query(1,500000,0) << endl;
// UPSTREAM UPDATE
update(int(pos_cur),dp[i]+d*pos_cur,1);
// cout << i << " " << dp[i] << endl;
}
ll ans=0;
REP(i,1,n)
{
ll cur_pos = ll(get<1>(fairs[i]));
ll cur_ans=dp[i];
if(cur_pos>=s) cur_ans-=u*(cur_pos-s); // downstream
else cur_ans-=d*(s-cur_pos);
ans=max(ans,cur_ans);
}
cout << ans << endl;
}
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |