Submission #445266

#TimeUsernameProblemLanguageResultExecution timeMemory
445266qwerasdfzxclSalesman (IOI09_salesman)C++14
100 / 100
997 ms47416 KiB
#include <bits/stdc++.h> typedef long long ll; using namespace std; const int MX = 500500; struct Seg{ vector<ll> tree; int sz; void init(int n, vector<ll> &vec){ sz = n; tree.resize(sz*2); if (!vec.empty()) for (int i=0;i<sz;i++) tree[i+sz] = vec[i]; else fill(tree.begin()+sz, tree.begin()+sz*2, -1e18); for (int i=sz-1;i;i--) tree[i] = max(tree[i<<1], tree[i<<1|1]); } void update(int x, ll val){ for (tree[x+=sz] = val;x>1;x>>=1) tree[x>>1] = max(tree[x], tree[x^1]); } ll query(int l, int r){ ll ret = -1e18; for (l+=sz, r+=sz;l<r;l>>=1, r>>=1){ if (l&1) ret = max(ret, tree[l++]); if (r&1) ret = max(ret, tree[--r]); } return ret; } }tree1, tree2; vector<pair<int, int>> a[500500]; ll dp[500500]; int main(){ int n, u, d, s; scanf("%d %d %d %d", &n, &d, &u, &s); for (int i=0;i<n;i++){ int t, l, m; scanf("%d %d %d", &t, &l, &m); a[t].emplace_back(l, m); } for (int i=1;i<MX;i++) sort(a[i].begin(), a[i].end()); fill(dp+1, dp+MX, -1e18); dp[s] = 0; vector<ll> tmp; tree1.init(MX, tmp); tree2.init(MX, tmp); tree1.update(s, dp[s]-s*d); tree2.update(s, dp[s]-(MX-s)*u); for (int T=1;T<MX;T++){ if (a[T].empty()) continue; int sz = a[T].size(); vector<ll> ranL(sz+1, -1e18), ranR(sz+1, -1e18); vector<ll> SL(sz), SR(sz); SL[0] = a[T][0].second - (u+d)*a[T][0].first; SR[sz-1] = a[T][sz-1].second - (u+d)*(MX-a[T][sz-1].first); for (int i=1;i<sz;i++) SL[i] = SL[i-1] + a[T][i].second - (u+d)*(a[T][i].first-a[T][i-1].first); for (int i=sz-2;i>=0;i--) SR[i] = SR[i+1] + a[T][i].second - (u+d)*(a[T][i+1].first-a[T][i].first); vector<ll> TL(sz), TR(sz); TL[0] = a[T][0].second - d*(a[T][0].first); TR[sz-1] = a[T][sz-1].second - u*(MX-a[T][sz-1].first); for (int i=1;i<sz;i++) TL[i] = TL[i-1] + a[T][i].second - d*(a[T][i].first-a[T][i-1].first); for (int i=sz-2;i>=0;i--) TR[i] = TR[i+1] + a[T][i].second - u*(a[T][i+1].first-a[T][i].first); Seg tree3, tree4; tree3.init(sz, SL); tree4.init(sz, SR); ll cur1 = 0; for (int i=0;i<sz;i++){ cur1 += a[T][i].second; int cur = a[T][i].first+1, nxt = MX; if (i!=sz-1) nxt = a[T][i+1].first; ll tmp1 = tree1.query(cur, nxt) + (d*(cur-1)); ll tmp2 = tree2.query(cur, nxt) - (d*(nxt-cur+1)) + (u*(MX-nxt)); tmp2 += tree3.query(i+1, sz) + (u+d)*nxt - cur1; ranL[i] = max(tmp1, tmp2)+TL[i]; //if (a[T][i].first==75) printf("%lld %lld\n", tmp1, tmp2); } cur1 = 0; for (int i=sz-1;i>=0;i--){ cur1 += a[T][i].second; int cur = a[T][i].first, nxt = 1; if (i) nxt = a[T][i-1].first+1; ll tmp1 = tree2.query(nxt, cur) + (u*(MX-cur)); ll tmp2 = tree1.query(nxt, cur) - (u*(cur-nxt+1)) + (d*(nxt-1)); tmp2 += tree4.query(0, i) + (u+d)*(MX-(nxt-1)) - cur1; ranR[i] = max(tmp1, tmp2)+TR[i]; } Seg tree5, tree6; tree5.init(sz, ranL); tree6.init(sz, ranR); for (int i=0;i<sz;i++){ int cur = a[T][i].first; ll tmp1 = tree5.query(i, sz) - TL[i] + a[T][i].second; ll tmp2 = tree6.query(0, i+1) - TR[i] + a[T][i].second; dp[cur] = max(tmp1, tmp2); tree1.update(cur, dp[cur]-cur*d); tree2.update(cur, dp[cur]-(MX-cur)*u); //printf("%d: %lld %lld %lld\n", cur, dp[cur], tmp1, tmp2); } } ll ans = 0; for (int i=1;i<s;i++) ans = max(ans, dp[i] - u*(s-i)); for (int i=s+1;i<MX;i++) ans = max(ans, dp[i] - d*(i-s)); printf("%lld\n", ans); return 0; }

Compilation message (stderr)

salesman.cpp: In function 'int main()':
salesman.cpp:33:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   33 |     scanf("%d %d %d %d", &n, &d, &u, &s);
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
salesman.cpp:36:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   36 |         scanf("%d %d %d", &t, &l, &m);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...