【Codeforces Round #437 (Div. 2) C】 Ordering Pizza

Keywords: REST

[link] h Write links here


[title]


Give you the number of competitors and an integer S to indicate the number of pieces per pizza.
Each parameter has three parameters, si,ai,bi;
Indicate the number of pizza pieces that the first contestant wants to eat and the increased happiness of eating the first pizza.
And eating a second pizza increases happiness.

Both pizzas can be ordered in any quantity.
But the total num has an upper limit.
S*num>=si
num is the smallest.
That means giving you a num.
Ask you how many a,b(a+b==num) you need to buy for each pizza.
Make the contestants as happy as possible.
(Participants can choose either the first or the second one at the same time)

[Abstract]


If the number of pizzas each person wants and <=S
Then you can only buy one pizza.
If you buy a or b, then everyone can only choose A or B.
Better value.

Where is the contradiction?
Although your a is big, there is no A pizza for you.
Or, it's better to buy all B pizza.

Enumerate how many B pizzas you finally bought
    i=0
Pizza was eaten all the time.
    i=1
Make the former S-olds of B-A eat B-pizza
    i=2
Make the first 2S B-A adults eat B-pizza
Change it on the basis of i=i-1
Record who the person is and how much more that person can get from A - > B

The maximum I is num and i*S<=si

B-A is the key word in descending order?

[Number of errors]


0

[introspection]


The way to add notes is really good.

[Code]

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int N = 1e5;

struct abc{
    ll a,b,rest,c;
};

int n;
ll S,temp,num,srest,ans;
abc a[N+10];

bool cmp(abc a,abc b)
{
    return a.c > b.c;
}

int main()
{
    //freopen("F:\\rush.txt","r",stdin);
    scanf("%d%lld",&n,&S);
    for (int i = 1;i <= n;i++){
        scanf("%lld%lld%lld",&a[i].rest,&a[i].a,&a[i].b);
        a[i].c = a[i].b-a[i].a;
        temp += a[i].rest*a[i].a;
        srest += a[i].rest;
    }

    //Get the maximum number of pizzas you can buy
    ll l = 1,r = 1e10 + 100;
    while (l <= r)
    {
        ll mid = (l+r)>>1;
        ll temp = mid*S;
        if (temp >= srest)
        {
            num = mid;
            r = mid - 1;
        }else
            l = mid + 1;
    }

    sort(a+1,a+1+n,cmp);//In descending order B-A

    ans = temp;//Start with all pizza A
    //The value of this num may be very large, and you may not be able to enumerate all of it.
    //If possible, try to choose greedily. As long as the number of B pizzas does not exceed num
    ll temp1 = 0,tnum = 0;//tnum is the number remaining to become B better
    //temp1 is the incremental value of the answers after they become B.

    ll spe = num*S-srest;//Number of Pizza Pizzas Overbought
    //S slice to make up a B pizza

    for (int i = 1;i <= n;i++)
    {
        //Some of the first people turned to Pizza B.

        if (a[i].c < 0)//The answer decreases when the person becomes B.
        {//Use spe to try not to let him reduce - > There must have been some people from a to B, now you can use the extra filling, do not let them change.
            //Premise is
            if (tnum + a[i].rest + spe >= S)//That's enough.
            {
                ll dd = tnum + spe;
                if (dd >= S)//It can be surpassed without adding.
                {
                    ans = max(ans,temp + temp1);
                }else
                {
                    ll js = S-dd;
                    ans = max(ans,temp + temp1 + a[i].c*js);
                }
                temp1 = 0;
                break;
            }
        }
        if (tnum + a[i].rest < S)//If not more than one piece of pizza
        {
            temp1 += a[i].rest*a[i].c;
            tnum += a[i].rest;
        }else//Exceeded
        {
            //How many a - > b did this person choose?
            temp += temp1;//Priority plus precedence

            ll rr = (a[i].rest + tnum)%S;//Remainder
            ll choose = a[i].rest-rr;//Then add the current one.
            temp += choose*a[i].c;

            tnum = rr;//The rest of the previous wheels became rr
            temp1 = rr*a[i].c;//temp1 becomes rr*a[i].c

            ans = max(ans,temp);//Maximum value
            //Obviously B will be enough in this process.
        }
    }
    //temp1 = 1;
    //printf("%lld\n",temp1);
    if (tnum + spe >= S)//The last remaining possibilities of all positive numbers can also make up an S with redundant ones.
    {
        ans = max(ans,temp + temp1);
    }

    printf("%lld\n",ans);
    return 0;
}

Posted by dnoonan on Sun, 10 Feb 2019 20:51:18 -0800