• Sagheer and Nubian Market CodeForces


    On his trip to Luxor and Aswan, Sagheer went to a Nubian market to buy some souvenirs for his friends and relatives. The market has some strange rules. It contains n different items numbered from 1 to n. The i-th item has base cost aiEgyptian pounds. If Sagheer buys k items with indices x1, x2, ..., xk, then the cost of item xj is axj + xj·k for 1 ≤ j ≤ k. In other words, the cost of an item is equal to its base cost in addition to its index multiplied by the factor k.

    Sagheer wants to buy as many souvenirs as possible without paying more than SEgyptian pounds. Note that he cannot buy a souvenir more than once. If there are many ways to maximize the number of souvenirs, he will choose the way that will minimize the total cost. Can you help him with this task?

    Input

    The first line contains two integers n and S (1 ≤ n ≤ 105 and 1 ≤ S ≤ 109) — the number of souvenirs in the market and Sagheer's budget.

    The second line contains n space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 105) — the base costs of the souvenirs.

    Output

    On a single line, print two integers kT — the maximum number of souvenirs Sagheer can buy and the minimum total cost to buy these k souvenirs.

    Examples

    Input
    3 11
    2 3 5
    Output
    2 11
    Input
    4 100
    1 2 5 6
    Output
    4 54
    Input
    1 7
    7
    Output
    0 0

    Note

    In the first example, he cannot take the three items because they will cost him [5, 9, 14] with total cost 28. If he decides to take only two items, then the costs will be [4, 7, 11]. So he can afford the first and second items.

    In the second example, he can buy all items as they will cost him [5, 10, 17, 22].

    In the third example, there is only one souvenir in the market which will cost him 8pounds, so he cannot buy it.

    题目比较狗血,中文题面点击这里。https://vjudge.net/problem/CodeForces-812C#author=ChineseOJ

    思路:

    根据题意可知,要买的商品个数ans越多,那么每一个商品的价格就越高,价格高导致实力能负担得起的商品数量又下降,

    那么我们可以知道 可以购买到的商品数量和打算购买的商品数量呈单调关系,

    那么如果是单调关系即可以进行二分了。

    二分购买的商品数量ans,范围是[0,n] 

    然后每一次O(n*logn)去检查mid是否满足条件,

    所以总时间复杂度为O( n*logn*logn ) n上限为1e5,所以可以满足。

    那么如何检查一个ans是否满足呢?

    首先根据题目给的公式把实际购买的价格算出来,然后排序,贪心的选取价格比较小的那ans个,如果sum和小于等于S,即满足条件return 1;

    更多细节见我的代码哦:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #define sz(a) int(a.size())
    #define all(a) a.begin(), a.end()
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define gg(x) getInt(&x)
    #define db(x) cout<<"==  "<<x<<"  =="<<endl;
    using namespace std;
    typedef long long ll;
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
    inline void getInt(int* p);
    const int maxn=1000010;
    const int inf=0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    ll n;
    ll m;
    ll a[maxn];
    ll b[maxn];
    ll sum[maxn];
    bool check(ll mid)
    {
        sum[0]=0ll;
        for(ll i=1ll;i<=n;i++)
        {
            b[i]=a[i]+i*mid;
            // sum[i]=b[i]+sum[i-1];
        }
        sort(b+1,b+1+n);
        for(ll i=1ll;i<=mid;i++)
        {
            sum[i]=b[i]+sum[i-1];
        }
        return m>=sum[mid];
    }
    int main()
    {
        gbtb;
        cin>>n>>m;
        repd(i,1,n)
        {
             cin>>a[i];
        }
        // sort(a+1,a+1+n);
        ll l=0;
        ll r=n;
        ll mid;
        ll ans=0;
        ll ANS=0ll;
        while(l<=r)
        {
            mid=(l+r)>>1;
            if(check(mid))
            {
                ans=mid;
                ANS=sum[mid];
                l=mid+1;
            }else
            {
                r=mid-1;
            }
        }
        cout<<ans<<" "<<ANS<<endl;
        return 0;
    }
    
    inline void getInt(int* p) {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        }
        else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    光庭杯第九题
    NYOJ 95
    NYOJ 31
    NYOJ 26
    HDOJ 1016(DFS)
    memset和memcpy和memcpy
    周期串
    C# BackgroudWorker
    Microsoft® SQL Server® 2008 Express以及Microsoft® SQL Server® 2008 R2 SP1下载地址
    事件(Event)
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/10298948.html
Copyright © 2020-2023  润新知