往年周赛选拔赛题解合集(hard)

先修正一波自己数据结构以及dp上的弱点。
接下来一小周主要补题+打重现赛
------------------------------------------ 持续更新中
CSUST 3034
这是一个二分的题目。首先观察到每行是单调的 ,然后我们先预处理一下整个矩阵的数据范围,L R经行二分。 题目问我们当前矩阵第K大的是哪一个元素,那么我们就二分答案,去check这个mid值 在矩阵里面有多少个数严格比他小。因为矩阵有n行 ,那么很容易可以计算得到这个mid 值在我们枚举的行里面 排第几大,并算一下有多少个数严格比他小。最终我们return 回去这个严格小的值, 如果check(mid)==K 那么我们继续往大的方向二分

#include<bits/stdc++.h>
#define ll long long

using namespace std;

ll n,m,k;
ll a,b,c;
ll check(ll x)
{
    
    

    ll cnt=0;
    if(c==0)
    {
    
    
        for(int i=1; i<=n; i++)
        {
    
    
            ll op=a*i*i+b*i;
            if(op<x)
            {
    
    
                cnt=cnt+m;
            }

        }


    }

    if(c>0)
    {
    
    
// 递增
        for(int i=1; i<=n; i++)
        {
    
    
            ll vel=a*i*i+b*i;
            ll pos=(x-vel)/c;// >=

            if(pos>0)
            {
    
    
                //cnt=cnt+min(pos,m);
                if(pos>m)
                {
    
    
                    cnt+=m;
                    continue;
                }
                if((x-vel)%c==0)
                {
    
    
                    cnt=cnt+pos-1;
                }
                if((x-vel)%c!=0)
                {
    
    
                    cnt=cnt+pos;
                }

            }

        }



    }


    if(c<0)
    {
    
    
//
        for(int i=1; i<=n; i++)
        {
    
    
            ll vel=a*i*i+b*i;
            ll pos=(x-vel)/c;// >=


            if(pos<=0)
            {
    
    
                cnt=cnt+m;
                continue;

            }
            if(pos>0)
            {
    
    

                if(pos>m)
                {
    
    
                    continue;
                }
                else
                {
    
    


                    cnt=cnt+(m-pos);

                }

            }


        }



    }

    return cnt;
}
signed main()
{
    
    


    scanf("%lld%lld%lld%lld%lld%lld",&n,&m,&k,&a,&b,&c);
    ll l=1e18;
    ll r=-1e18;

    for(int i=1; i<=n; i++)
    {
    
    

        if(c>0)
        {
    
    
            l=min(l,a*i*i+b*i+c);
            r=max(r,a*i*i+b*i+c*m);
        }
        else
        {
    
    
            l=min(l,a*i*i+b*i+c*m);
            r=max(r,a*i*i+b*i+c);

        }

    }
    ll ans=0;

    ll opp=0;

    while(l<=r)
    {
    
    

        ll mid=(l+r)/2;
        ll rnm=check(mid);
        if(rnm<=(n*m-k))
        {
    
    
            l=mid+1;
            ans=mid;

        }

        if(rnm>(n*m-k))
        {
    
    
            r=mid-1;
        }

    }
    printf("%lld",ans);

}

猜你喜欢

转载自blog.csdn.net/weixin_45948940/article/details/113747323
今日推荐