This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include"holiday.h"
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int nx=1e5+5, dx=250005;
int id[nx], st, N, D;
ll ans, dp[4][dx];
vector<pair<ll, int>> v;
struct segtree
{
int f[4*nx];
ll sm[4*nx];
void build(int l, int r, int i)
{
f[i]=sm[i]=0;
if (l==r) return;
int md=(l+r)/2;
build(l, md, 2*i);
build(md+1, r, 2*i+1);
}
void update(int l, int r, int i, int idx, ll val)
{
if (idx<l||r<idx) return;
if (l==r)
{
if (val>=0) return f[i]=1, sm[i]=val, void();
else return f[i]=sm[i]=0, void();
}
int md=(l+r)/2;
update(l, md, 2*i, idx, val);
update(md+1, r, 2*i+1, idx, val);
f[i]=f[2*i]+f[2*i+1];
sm[i]=sm[2*i]+sm[2*i+1];
}
ll query(int l, int r, int i, int cnt)
{
if (cnt>=f[i]) return sm[i];
if (cnt<=0) return 0;
int md=(l+r)/2;
if (f[2*i]>cnt) return query(l, md, 2*i, cnt);
return sm[2*i]+query(md+1, r, 2*i+1, cnt-f[2*i]);
}
} s;
void solver(int st, int ml, int sl)
{
int lst=st-1+(ml==2);
queue<tuple<int, int, int, int>> q;
q.push({0, D, st+(ml==2), N-1});
if ((st+(ml==2))>N-1) return;
while (!q.empty())
{
auto [l, r, optl, optr]=q.front();
q.pop();
if (r<l) continue;
int md=(l+r+1)/2;
pair<ll, int> p={-1, -1};
for (int i=optl; i<=optr; i++)
{
while (lst<i) ++lst, s.update(0, N-1, 1, id[lst], v[id[lst]].first);
while (lst>i) s.update(0, N-1, 1, id[lst], -1), lst--;
p=max(p, make_pair(s.query(0, N-1, 1, md-ml*(i-st)), i));
}
dp[sl][md]=p.first;
q.push({l, md-1, optl, p.second});
q.push({md+1, r, p.second, optr});
}
s.build(0, N-1, 1);
}
void solvel(int st, int ml, int sl)
{
int lst=st+1-(ml==2);
queue<tuple<int, int, int, int>> q;
q.push({0, D, 0, st-(ml==2)});
if ((st-(ml==2))<0) return;
while (!q.empty())
{
auto [l, r, optl, optr]=q.front();
q.pop();
if (r<l) continue;
int md=(l+r+1)/2;
pair<ll, int> p={-1, -1};
for (int i=optl; i<=optr; i++)
{
while (lst>i) --lst, s.update(0, N-1, 1, id[lst], v[id[lst]].first);
while (lst<i) s.update(0, N-1, 1, id[lst], -1), lst++;
p=max(p, make_pair(s.query(0, N-1, 1, md-ml*(st-i)), i));
}
dp[sl][md]=p.first;
q.push({l, md-1, p.second, optr});
q.push({md+1, r, optl, p.second});
}
s.build(0, N-1, 1);
}
long long int findMaxAttraction(int n, int start, int d, int attraction[]) {
v.resize(n);
for (int i=0; i<n; i++) v[i]={attraction[i], i};
sort(v.begin(), v.end());
reverse(v.begin(), v.end());
for (int i=0; i<n; i++) id[v[i].second]=i;
N=n; D=d; st=start;
solver(st, 1, 0);
solver(st, 2, 1);
solvel(st, 1, 2);
solvel(st, 2, 3);
for (int i=0; i<=D; i++) ans=max(ans, dp[0][i]+dp[3][D-i]);
for (int i=0; i<=D; i++) ans=max(ans, dp[1][i]+dp[2][D-i]);
return ans;
}
# | 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... |