假 设健佳有 7 天假期,有 5 个城市(参见下表),而且他由城市 2 开始。在第一天,健佳参观城市2的 20 个景点。第二天,健佳由城市 2 去往城市 3。而在第三天,健佳参观城市 3 的30 个景点。接下来的3天,健佳由城市 3 前往城市 0。而在第 7 天,健佳参观城市0的 10 个景点。这样健佳参观的景点总数是20+30+10=60,这是他由城市 2 开始、在 7 天假期内最多能参观的景点数目。
#include <cstring>
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=100010;
int n,S,m,tot,N,cost;
int v[maxn],rt[maxn];
ll ans;
ll f1[maxn<<1],g1[maxn<<1],f2[maxn*3],g2[maxn*3],ref[maxn];
struct sag
{
int ls,rs,siz;
ll sum;
}s[maxn*20];
struct number
{
int val,org;
}num[maxn];
void insert(int x,int &y,int l,int r,int a)
{
y=++tot,s[y]=s[x],s[y].siz++,s[y].sum+=ref[a];
if(l==r) return ;
int mid=(l+r)>>1;
if(a<=mid) insert(s[x].ls,s[y].ls,l,mid,a);
else insert(s[x].rs,s[y].rs,mid+1,r,a);
}
ll query(int x,int l,int r,int y)
{
if(y<0) return -1;
if(!y) return 0;
if(!x||y>=s[x].siz) return s[x].sum;
if(l==r) return y*ref[l];
int mid=(l+r)>>1;
if(s[s[x].rs].siz>=y) return query(s[x].rs,mid+1,r,y);
else return s[s[x].rs].sum+query(s[x].ls,l,mid,y-s[s[x].rs].siz);
}
void solve(ll *f,int l,int r,int L,int R)
{
if(l>r) return ;
int mid=(l+r)>>1,MID=0,i;
ll tmp,mx=-1;
for(i=L;i<=R;i++)
{
tmp=query(rt[i],1,N,mid-i*cost);
if(tmp>mx) mx=tmp,MID=i;
}
f[mid]=mx;
solve(f,l,mid-1,L,MID);
solve(f,mid+1,r,MID,R);
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<‘0‘||gc>‘9‘) {if(gc==‘-‘) f=-f; gc=getchar();}
while(gc>=‘0‘&&gc<=‘9‘) ret=ret*10+gc-‘0‘,gc=getchar();
return ret*f;
}
bool cmp(number a,number b)
{
return a.val<b.val;
}
int main()
{
n=rd(),S=rd()+1,m=rd();
int i;
for(i=1;i<=n;i++) num[i].val=rd(),num[i].org=i;
sort(num+1,num+n+1,cmp);
for(i=1;i<=n;i++)
{
if(i==1||num[i].val>ref[N]) ref[++N]=num[i].val;
v[num[i].org]=N;
}
for(i=1;i<S;i++) insert(rt[i-1],rt[i],1,N,v[S-i]);
cost=1,solve(f1,0,(S-1)*2,0,S-1);
cost=2,solve(f2,0,(S-1)*3,0,S-1);
memset(s,0,sizeof(s[0])*(tot+5));
tot=0;
for(i=0;i<=n-S;i++) insert(rt[max(i-1,0)],rt[i],1,N,v[S+i]);
cost=1,solve(g1,0,(n-S)*2+1,0,n-S);
cost=2,solve(g2,0,(n-S)*3+1,0,n-S);
for(i=0;i<=m;i++)
{
ans=max(ans,max(f1[min(i,(S-1)*2)]+g2[min(m-i,(n-S)*3+1)],f2[min(i,(S-1)*3)]+g1[min(m-i,(n-S)*2+1)]));
}
printf("%lld",ans);
return 0;
}