2019 icpc徐州现场赛A题

2019 icpc徐州现场赛A题

题意:

给你三个数l,r,s。l,r代表存在区间(l,r),s表示你有多少钱,此时你要取一段连续的数,若你要取x到y,则你要花费的钱为x到y之间的所有值的亦或(即x ^ (x+1) ^ (x+2)…(y-1) ^ y,且x,y均在l,r区间内,x<=y),问能连续取的最大区间长度,若长度为0输出-1。

思路:

首先亦或值是在二进制下的计算,所以可以根据四亦或值为零这个原理来判断:
___00 ^ ___01 ^ ___10 ^ ___11=0(二进制),若取最长则中间所有可以四个连续亦或为0的(如上)都取,此时中间取的都是连续的,而前后两边最多各剩3个,所以只需要一一枚举前后的个数即可。

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
int main(){
    ll l,r,s;
    while(scanf("%lld%lld%lld",&l,&r,&s)==3){
        ll sum=0,ans=0;
        for(ll i=l;i<=r;i++) sum^=i;
        for(int pre=0;pre<=3;pre++){
            for(int h=0;h<=3;h++){
                ll dns=sum;
                for(ll i1=0;i1<pre&&i1+l<=r;i1++){
                    dns^=l+i1;
                }
                for(ll i1=0;i1<h&&r-i1>=l;i1++){
                    dns^=r-i1;
                }
                if(dns<=s)
                ans=max(ans,r-l+1-pre-h);
            }
        }
        if(ans)
        printf("%lld\n",ans);
        else printf("-1\n");
    }
}

扩展 :

cf上也有道题也有用到了___00 ^ ___01 ^ ___10 ^ ___11=0这个结论的一道构造题,链接:codeforces 1208C,(总结这是一道水题,而且我还做过类似的,但因我在现场赛错把连续的读成了任意导致拖延了队友的进度和多发罚时,故写此博客提醒自己多读题/哭)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值