牛客挑战赛45 C-友人

友人

https://ac.nowcoder.com/acm/contest/8563/C

友人

分析

  • 先掏出式子
    图片说明
    可以发现,如果确定了图片说明 的值,那么z的合法范围就可以求出来,并且图片说明 ,完全可以图片说明 枚举。接下来考虑右边的括号。首先我们已经有了z的范围[1,max],如果k第i位为1,那么z的第i位在满足图片说明 的条件下也得为1,这样原式相当于就会减小图片说明 ,如果k这一位为0,z这一位也应为0,因为如果为1,根据异或的性质,前面的异或结果会增加图片说明 ,而后面的会减少图片说明 ,什么也没变,但是我z却变大了,不就亏了吗。

代码

/*
(写点什么吧...)
*/
#include<bits/stdc++.h>

#define R register
#define ll long long
#define inf INT_MAX

using namespace std;

const int N=1e5+10;

ll n,st,d,k,ma;
ll a[N],b[N];

int main()
{
    scanf("%lld%lld%lld%lld%lld",&n,&st,&d,&k,&ma);
    for (ll i=1;i<=n;i++)
        a[i]=st+(i-1ll)*d,b[i]=b[i-1]+a[i];

    ll ans=(1ll<<62);
    for (ll i=1;i<=n;i++)
    {//枚举r-l+1
        ll l=0,r=a[n-i+1],z=-1;
        while(l<=r)
        {
            ll mid=(l+r)/2;
            ll now=b[n-i]+i*mid;
            if(now<=ma) z=mid,l=mid+1;
            else r=mid-1;
        }//找到z的最大值

        if(z<0) continue;

        ll las=0;
        for (ll j=40;j>=0;j--)
            if((k>>j)&1)
            {
                ll ok=(1ll<<j)+las;
                if(ok<=z) las=ok;
            }

        ans=min(ans,i*((las^k)+k-las));
    }

    if(b[n]<=ma) ans=0;
    printf("%lld\n",ans);

    return 0;
}
比赛题解 文章被收录于专栏

牛客IOI周赛,团队赛,练习赛,挑战赛,各种模拟赛的部分题解

全部评论

相关推荐

一颗宏心:华为HR晚上过了十二点后还给我法消息。
点赞 评论 收藏
分享
把球:这个听过,你加了就会发现是字节的hr
点赞 评论 收藏
分享
评论
6
收藏
分享
牛客网
牛客企业服务