AtCoder Beginner Contest 289 G. Shopping in AtCoder store (Offline Convex Hull/Online Convex Hull Upper Divide/Online Dynamic Opening Point Li Chaoshu)

topic

n(n<=2e5) individuals, m(m<=2e5) items,

The motivation of the i-th person is bi (0<=bi<=1e9), and the value of the j-th item is cj (0<=cj<=1e9)

Takahashi can price each item, where the jth item is priced pj,

The i-th person will buy the j-th item if and only if bi+cj>=pj

Now it is required to maximize the commodity revenue (that is, to maximize the sum of people who buy the jth item *pj),

For each item j, output the revenue that maximizes the jth item

source of ideas

Although I have done it myself, I will summarize it

answer

//(a1+b1)*5 (a2+b1)*4 (a3+b1)*3 (a4+b1)*2 (a5+b1)*1
//(a1+b2)*5 (a2+b2)*4 (a3+b2)*3 (a4+b2)*2 (a5+b2)*1
//c1+b1*5 c2+b1*4 c3+b1*3 c4+b1*2 c5+b1
//2+x*5 6+x*4 8+x*3 2+x*2 4+x
//2+x*5<6+x*4 x<4
//2+x*5<8+x*3 2x<6 x<3

Looking at this example, for the first item,

When pricing x=100+120, the profit is 5*(100+120)

When pricing x=200+120, the profit is 4*(200+120)

...

When pricing x=b[the i-th value from large to small]+c[1], the income y=i*(b[i]+c[1])=i*c[1]+i*b[i ]

The income can be regarded as a function of y=kx+b, where k=i, b=i*b[i], and x is c[1]

Therefore, it is equivalent to having n straight lines, where the variable is cj, which can be regarded as x

According to the value of x changing from small to large, the optimal straight line of income y may be the best straight line among n

Therefore, just find the optimal straight line with the largest y value, construct a convex hull or query according to x on the Li Chao tree

Here is an offline approach. First construct the convex hull, then sort the cj values ​​offline in increasing order, and keep scanning forward in the convex hull to construct the answer

Because the value range is 1e9, Li Chaoshu's method needs to be opened dynamically, which is a board question.

You can refer to the board borrowed from zhoukangyang:

Dynamic opening point Li Chaoshu (example + board summary)_Code92007's Blog-CSDN Blog

the code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const db eps=1e-8;
const int N=2e5+10,M=2e5+10;
struct node{
    int c,id;
}f[N];
bool operator<(node a,node b){
    return a.c<b.c;
}
struct line{
    ll k,b;
    ll cal(int x){
        //printf("k:%lld v:%lld b:%lld ans:%lld\n",k,v,b,1ll*k*v+b);
        return 1ll*k*x+b;
    }
}l[N],stk[N];
bool cmp(line a,line b){
    return a.k<b.k||(a.k==b.k && a.b<b.b);
}
db crossx(line a,line b){
    return (b.b-a.b)/(a.k-b.k);
}
int n,m,c,b[N];
ll ans[N];
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        scanf("%d",&b[i]);
    }
    sort(b+1,b+n+1,greater<int>());
    for(int i=1;i<=n;++i){
        l[i].k=i;
        l[i].b=1ll*i*b[i];
        //printf("k:%lld b:%lld\n",l[i].k,l[i].b);
    }
    for(int i=1;i<=n;++i){
        while(c){
            if(stk[c].k==l[i].k)c--;
            else if(c>1 && 1ll*(l[i].b-stk[c].b)*(stk[c-1].k-stk[c].k)<=1ll*(stk[c].b-stk[c-1].b)*(stk[c].k-l[i].k))c--;
            else break;
        }
        stk[++c]=l[i];
    }
    for(int i=1;i<=m;++i){
        scanf("%d",&f[i].c);
        f[i].id=i;
    }
    sort(f+1,f+m+1);
    int p=1;
    for(int i=1;i<=m;++i){
        //printf("i:%d c:%d cal:%lld\n",i,f[i].c,stk[p].cal(f[i].c));
        while(p+1<=c && stk[p].cal(f[i].c)<=stk[p+1].cal(f[i].c))p++;
        //printf("i:%d p:%d k:%lld b:%lld\n",i,p,stk[p].k,stk[p].b);
        ans[f[i].id]=stk[p].cal(f[i].c);
    }
    for(int i=1;i<=m;++i){
        printf("%lld%c",ans[i]," \n"[i==m]);
    }
    return 0;
}
//(a1+b1)*5 (a2+b1)*4 (a3+b1)*3 (a4+b1)*2 (a5+b1)*1
//(a1+b2)*5 (a2+b2)*4 (a3+b2)*3 (a4+b2)*2 (a5+b2)*1
//c1+b1*5 c2+b1*4 c3+b1*3 c4+b1*2 c5+b1
//2+x*5 6+x*4 8+x*3 2+x*2 4+x
//2+x*5<6+x*4 x<4
//2+x*5<8+x*3 2x<6 x<3

Guess you like

Origin blog.csdn.net/Code92007/article/details/129228131