제출 #124761

#제출 시각아이디문제언어결과실행 시간메모리
124761arthurconmySalesman (IOI09_salesman)C++14
62 / 100
529 ms27640 KiB
// 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 timeMemoryGrader output
Fetching results...