이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include "fish.h"
#include <bits/stdc++.h>
using namespace std;
#ifndef _IN_LOCAL
#define dbg(...)
#endif
#define endl '\n'
#define endlfl '\n' << flush
#define quit(x) return (void)(cout << x << endl)
template<typename T> void read(T& x) { cin >> x;}
template<typename T1, typename T2> void read(pair<T1, T2>& p) { read(p.first), read(p.second);}
template<typename T> void read(vector<T>& v) { for (auto& x : v) read(x); }
template<typename T1, typename T2> void read(T1& x, T2& y) { read(x), read(y); }
template<typename T1, typename T2, typename T3> void read(T1& x, T2& y, T3& z) { read(x), read(y), read(z); }
template<typename T1, typename T2, typename T3, typename T4> void read(T1& x, T2& y, T3& z, T4& zz) { read(x), read(y), read(z), read(zz); }
template<typename T> void print(vector<T>& v) { for (auto& x : v) cout << x << ' '; cout << endl; }
#define sz(x) (int)(x.size())
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define pb push_back
#define mp(a, b) make_pair(a, b)
#define fi first
#define se second
#define cmin(a, b) a = min(a, b)
#define cmax(a, b) a = max(a, b)
#define YES cout << "YES" << endl
#define NO cout << "NO" << endl
#define QYES quit("YES")
#define QNO quit("NO")
#define int long long
#define double long double
const int inf = numeric_limits<int>::max() / 4;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int MOD = 1e9+7, LOG=20;
int n;
vector<vector<pair<int, int>>> pref, is;
vector<vector<vector<vector<vector<int>>>>> memo;
vector<unordered_map<signed, unordered_map<signed, int>>> isnxt;
vector<vector<vector<int>>> lbs;
int lowb(int x, int y, int j) {
int valy=y; y+=2;
if (sz(lbs)<=x) lbs.resize(x+1);
if (sz(lbs[x])<=y) lbs[x].resize(y+1);
if (sz(lbs[x][y])<=j) lbs[x][y].resize(j+1, -1);
if (lbs[x][y][j]!=-1) return lbs[x][y][j];
int lb=lower_bound(all(is[x]), mp(is[x+valy][j].fi, -1LL))-is[x].begin();
return lbs[x][y][j]=lb;
}
int calc(int x, int l, int r) {
if (l>r || x>=n || x<0) return 0;
if (isnxt[x][l].count(r)) return isnxt[x][l][r];
auto lb=lower_bound(all(pref[x]), mp(r, -1LL));
if (lb->fi!=r) {
if (lb==pref[x].begin()) return 0;
lb--;
}
if (l==0) return isnxt[x][l][r]=lb->se;
int ans=lb->se;
lb=lower_bound(all(pref[x]), mp(l, -1LL)); if (lb==pref[x].begin()) return isnxt[x][l][r]=ans;
lb--;
return isnxt[x][l][r]=ans-lb->se;
}
int dp(int i, int j, int nb, bool before, bool taking) {
if (nb>=3 || i>=n) return 0;
if (sz(memo[i])<=j) memo[i].resize(j+1);
if (sz(memo[i][j])<=nb) memo[i][j].resize(nb+1);
if (sz(memo[i][j][nb])<=before) memo[i][j][nb].resize(before+1);
if (sz(memo[i][j][nb][before])<=taking) memo[i][j][nb][before].resize(taking+1, -1);
if (memo[i][j][nb][before][taking]!=-1) return memo[i][j][nb][before][taking];
int ans=0;
if (taking) {
if (nb==2) {
cmax(ans, dp(i+1, j, 0, 0, 0) + calc(i-1, 0, is[i][j].fi-1) + calc(i+1, 0, is[i][j].fi-1));
if (j+1<sz(is[i])) cmax(ans, dp(i, j+1, 2, 0, 1));
} else if (nb==1) {
cmax(ans, dp(i+1, j, 0, 0, 0) + calc(i+1, 0, is[i][j].fi-1));
if (before && j) cmax(ans, dp(i, j-1, 1, 1, 1));
else if (!before && j+1<sz(is[i])) cmax(ans, dp(i, j+1, 1, 0, 1)+calc(i-1, is[i][j].fi, is[i][j+1].fi-1));
} else {
if (i+1<n) {
int res=dp(i+2, j, 1, 0, 0);
int empl=lowb(i+1, -1, j), clc=pref[i+1][empl].se-is[i+1][empl].se;
if (!before) cmax(res, dp(i+1, empl, 0, 0, 1) - clc + calc(i, is[i][j].fi, is[i+1][empl].fi-1));
else if (empl) cmax(res, dp(i+1, empl-1, 0, 1, 1) + is[i+1][empl-1].se - clc);
// cout << res << ' ' << i << ' ' << j << ' ' << calc(i, is[i][j].fi, is[i+1][empl].fi-1) << endl;
cmax(ans, res + calc(i+1, 0, is[i][j].fi-1));
}
if (before && j) cmax(ans, dp(i, j-1, 0, 1, 1)+is[i][j-1].se);
else if (!before && j+1<sz(is[i])) cmax(ans, dp(i, j+1, 0, 0, 1) + calc(i-1, is[i][j].fi, is[i][j+1].fi-1));
}
} else {
cmax(ans, dp(i+1, j, nb+1, 0, 0));
if (nb==0) {
int empl=lowb(i, -1, j), clc=pref[i][empl].se-is[i][empl].se;
cmax(ans, dp(i, empl, 0, 0, 1) - clc + calc(i-1, is[i-1][j].fi, is[i][empl].fi-1));
if (empl) cmax(ans, dp(i, empl-1, 0, 1, 1) + is[i][empl-1].se - clc);
// cout << i << ' ' << empl << ' ' << clc << ' ' << dp(i, empl, 0, 1, 1) - clc << endl;
} else if (nb==1) {
int empl=0;
if (i-2>=0) empl=lowb(i, -2, j);
cmax(ans, dp(i, empl, 1, 0, 1));
if (empl) cmax(ans, dp(i, empl-1, 1, 1, 1));
} else {
cmax(ans, dp(i, 0, nb, 0, 1));
}
}
// cout << i << ' ' << j << ' ' << nb << ' ' << before << ' ' << taking << ' ' << ans << endl;
return memo[i][j][nb][before][taking]=ans;
}
int max_weights(signed N, signed m, vector<signed> x, vector<signed> y, vector<signed> w) {
n=N;
pref.resize(n), is.resize(n), memo.resize(n);
isnxt.resize(n);
for (int i=0; i<m; i++) {
is[x[i]].pb({y[i], w[i]});
}
for (int i=0; i<n; i++) {
sort(all(is[i]));
is[i].pb({n, 0});
int sm=0;
for (auto [j, x]: is[i]) {
sm+=x;
pref[i].pb({j, sm});
}
}
return dp(0, 0, 1, 0, 0);
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |