版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/syh0313/article/details/88855922
按美丽度排序,每次枚举必选那个,然后取前缀的len前k-1大
用个小根堆就可以维护
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <queue> using namespace std; int n,k,si; struct da{long long len,v;}a[3000100]; long long sum,ans; priority_queue<long long,vector<long long>,greater<long long> >s; bool cmp(da aa,da bb) { if (aa.v==bb.v) return aa.len>bb.len; return aa.v>bb.v; } int main() { scanf("%d%d",&n,&k); k--; for (int i=1;i<=n;i++) scanf("%lld%lld",&a[i].len,&a[i].v); sort(a+1,a+n+1,cmp); for (int i=1;i<=n;i++) { ans=max(ans,(sum+a[i].len)*a[i].v); if (si<k) s.push(a[i].len),si++,sum+=a[i].len; else if (si && s.top()<a[i].len) {sum-=s.top(); s.pop(); s.push(a[i].len); sum+=a[i].len;} } printf("%lld\n",ans); return 0; }
事后无聊写了一发主席树
ps:我已经在红标处跪了2~3次了,发此博客警醒一波
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>
#define lch a[n].lc
#define rch a[n].rc
using namespace std;
const int maxn=5e5;
int n,k,cnt,topt,root[maxn];
struct da{long long len,v;}aa[maxn];
struct dat{int lc,rc;long long sum,si;}a[maxn*20];
long long ans,v[maxn],ss;
map<long long,int>lc;
bool cmp(da aa,da bb)
{
if (aa.v==bb.v) return aa.len>bb.len;
return aa.v>bb.v;
}
bool cmp1(int aa,int bb){return aa>bb;}
void updata(int n)
{
a[n].sum=a[lch].sum+a[rch].sum;
a[n].si=a[lch].si+a[rch].si;
}
void build_tree(int &n,int l,int r)
{
n=++topt; a[n].sum=0; a[n].si=0;
if (l==r) return;
int mid=(l+r)>>1;
build_tree(lch,l,mid); build_tree(rch,mid+1,r); updata(n);
}
void tree_add(int old,int &n,int l,int r,int lc,long long k)
{
n=++topt; int mid=(l+r)>>1;
if (l==r && l==lc)
{a[n].si=a[old].si+1; a[n].sum=a[old].sum+k; return;}
if (lc<=mid) {rch=a[old].rc; tree_add(a[old].lc,lch,l,mid,lc,k);}
else {lch=a[old].lc; tree_add(a[old].rc,rch,mid+1,r,lc,k);}
updata(n);
}
long long qury(int n,int l,int r,int k)
{
if (!k) return 0;
int mid=(l+r)>>1;
if (l==r) return a[n].sum/a[n].si*k;
if (a[n].si==k) return a[n].sum;
if (a[lch].si<k)
{
long long ssu=a[lch].sum;
ssu+=qury(rch,mid+1,r,k-a[lch].si);
return ssu;
}
else return qury(lch,l,mid,k);
}
int main()
{
scanf("%d%d",&n,&k);
for (int i=1;i<=n;i++)
scanf("%lld%lld",&aa[i].len,&aa[i].v),v[i]=aa[i].len;
sort(aa+1,aa+n+1,cmp); sort(v+1,v+n+1,cmp1);
for (int i=1;i<=n;i++) if (!lc[v[i]]) lc[v[i]]=++cnt;
build_tree(root[0],1,cnt);
for (int i=1;i<=n;i++)
tree_add(root[i-1],root[i],1,cnt,lc[aa[i].len],aa[i].len);
for (int i=1;i<=n;i++)
{
ss=qury(root[i-1],1,cnt,min(i-1,k-1));
ans=max(ans,(ss+aa[i].len)*aa[i].v);
}
printf("%lld\n",ans);
return 0;
}