이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include"holiday.h"
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pii;
int n,st,d,p[100001];
ll dpL[250005][3],dpR[250005][3],val[100001];
bool visL[250005][3],visR[250005][3];
vector<pii> v;
struct node {
int sum;
int cnt;
node *l,*r;
node(int s, int c) : sum(s), cnt(c), l(NULL), r(NULL) {}
node(node *a, node *b) : sum(0), cnt(0), l(a), r(b) {
sum=a->sum+b->sum;
cnt=a->cnt+b->cnt;
}
};
vector<node*> arrR,arrL;
node* build(int l, int r) {
if (l==r) return new node(0,0);
else {
int mid=(l+r)/2;
return new node(build(l,mid),build(mid+1,r));
}
}
node* update(int l, int r, int x, ll val, node* pnode) {
if (x>r || x<l) return pnode;
if (l==r) return new node(val,1);
int mid=(l+r)/2;
return new node(update(l,mid,x,val,pnode->l),update(mid+1,r,x,val,pnode->r));
}
ll query(int l, int r, int want, node* pnode) {
if (want==0) return 0;
if (l==r) return pnode->sum;
int mid=(l+r)/2;
if (pnode->l->cnt<=want) return pnode->l->sum+query(mid+1,r,want-pnode->l->cnt,pnode->r);
else return query(l,mid,want,pnode->l);
}
void findR(int ld, int rd, int l, int r, int w) {
int day=(ld+rd)/2;
if (visR[day][w]) return;
visR[day][w]=true;
int best=st;
for (int i=l; i<=r; ++i) {
int tour=day-(i-st)*w;
if (tour<=0) continue;
ll h=query(0,n-1,tour,arrR[i-st]);
if (h>dpR[day][w]) {
dpR[day][w]=h;
best=i;
}
}
if (ld<=rd) {
findR(ld,day-1,l,best,w);
findR(day+1,rd,best,r,w);
}
}
void findL(int ld, int rd, int l, int r, int w) {
int day=(ld+rd)/2;
if (visL[day][w]) return;
visL[day][w]=true;
int best=st;
for (int i=l; i<=r; ++i) {
int tour=day-(st-i)*w;
if (tour<=0) continue;
ll h=query(0,n-1,tour,arrL[st-i]);
if (h>dpL[day][w]) {
dpL[day][w]=h;
best=i;
}
}
if (ld<=rd) {
findL(ld,day-1,best,r,w);
findL(day+1,rd,l,best,w);
}
}
ll findMaxAttraction(int N, int start, int D, int att[]) {
n=N; st=start; d=D;
for (int i=0; i<n; ++i) val[i]=att[i], v.push_back(pii(att[i],i));
sort(v.begin(),v.end(),greater<pii>());
for (int i=0; i<n; ++i) p[v[i].second]=i;
arrR.push_back(build(0,n-1));
arrL.push_back(build(0,n-1));
for (int i=st+1; i<n; ++i) arrR.push_back(update(0,n-1,p[i],val[i],arrR.back()));
for (int i=st-1; i>=0; --i) arrL.push_back(update(0,n-1,p[i],val[i],arrL.back()));
findR(0,d,st+1,n-1,1);
findR(0,d,st+1,n-1,2);
findL(0,d,0,st-1,1);
findL(0,d,0,st-1,2);
ll ans=0;
for (int i=0; i<=d; ++i) { //go right for i days
//go right first
ans=max(ans,dpR[i][2]+dpL[d-i][1]);
if (i!=d) ans=max(ans,dpR[i][2]+dpL[d-i-1][1]+val[st]);
//go left first
ans=max(ans,dpL[d-i][2]+dpR[i][1]);
if (i!=d) ans=max(ans,dpL[d-i-1][2]+dpR[i][1]+val[st]);
}
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... |