BestCoder Round #79 (div.1) Claris and XOR 题解。。。

题意没看清以为d>b…..结果比赛时没做出来
从高位往地位递推,递推时贪心选择最优解。
结论 1:递推到x位时,b此位的数必定>=a此位的数。d此位的数必定>=c此位的数。
证明:因为递推的过程不断刷新上下限,a和b的上一位一定相同,c和d的上一位一定相同,又因为b>=a,d>=c,所以可证
注意取模1LL!!!

#include<cstdio>
#define LL long long
int main()
{
   int t;
   scanf("%d",&t);
   while(t--)
   {
     LL a,b,c,d,aa,bb,cc,dd,ans = 0;
     scanf("%I64d%I64d%I64d%I64d",&a,&b,&c,&d);
     for(int i=62;i>=0;i--)
     {
         aa = a&(1LL<<i);   
         bb = b&(1LL<<i);
         cc = c&(1LL<<i);
         dd = d&(1LL<<i);
         if(!aa&&bb&&!cc&&dd)
         {
            ans+=(1LL<<(i+1))-1;//10000 和 01111 以后全为1 跳出
            break;
         }
         else if(dd&&!aa)//结论1 取两个区间此位的最大值和最小值
         {
            ans+=(1LL<<i);
            if(b&(1LL<<i))b = (1LL<<i)-1;
            if(!(c&(1LL<<i)))c = (1LL<<i);
         }
         else if(bb&&!cc) //同上
         {
            ans+=(1LL<<i);
            if(d&(1LL<<i))d = (1LL<<i)-1;
            if(!(a&(1LL<<i)))a = (1LL<<i);
         }
     }
     printf("%I64d\n",ans);
   }
}

第一发乱搞版。。。

#include<cstdio>
#define ll long long
long long t,a,b,c,d;
int main()
{
    scanf("%I64d",&t);
    while(t--)
    {
       scanf("%I64d%I64d%I64d%I64d",&a,&b,&c,&d);
       long long d1 = d,n = 0,ans = 0;
       for(ll i=62;i>=0;i--)
       {
          if((d&(1LL<<i))!=0&&(c&(1LL<<i))==0)
          {
             if((b&(1LL<<i))!=0&&(a&(1LL<<i))==0)
            {
                  ans+=(1LL<<i);
                  ans+=(1LL<<i)-1;
                  break;
            }
             else if((b&(1LL<<i))!=0&&(a&(1LL<<i))!=0)
             {
                 ans+=(1LL<<i);
                 for(ll j=0;j<=i;j++)
                  if(d&(1LL<<j))d-=(1LL<<j);
                 d+=((1LL<<i)-1);   
             }
            else if((b&(1LL<<i))==0&&(a&(1LL<<i))==0)
             {
                 ans+=(1LL<<i);
                 for(ll j=0;j<=i;j++)
                  if(c&(1LL<<j))c-=(1LL<<j);
                 c+=(1LL<<i);   
             }  
          }
          else if((d&(1LL<<i))!=0&&(c&(1LL<<i))!=0)
          {
            if((b&(1LL<<i))!=0&&(a&(1LL<<i))==0)
            {
                 ans+=(1LL<<i);
                 for(ll j=0;j<=i;j++)
                 if(b&(1LL<<j))b-=(1LL<<j);
                 b+=((1LL<<i)-1); 
            }
            else if((b&(1LL<<i))!=0&&(a&(1LL<<i))!=0)
            {
                ;
            }
            else if((b&(1LL<<i))==0&&(a&(1LL<<i))==0)
             {
                 ans+=(1LL<<i); 
             }  
          }
           else if((d&(1LL<<i))==0&&(c&(1LL<<i))==0)
           {
                if((b&(1LL<<i))!=0&&(a&(1LL<<i))==0)
               {
                  ans+=(1LL<<i);
                 for(ll j=0;j<=i;j++)
                  if(a&(1LL<<j))a-=(1LL<<j);
                  a+=(1LL<<i); 
               }
            else if((b&(1LL<<i))!=0&&(a&(1LL<<i))!=0)
            {
                ans+=(1LL<<i);
            }
            else if((b&(1LL<<i))==0&&(a&(1LL<<i))==0)
             {  
             }  
           }
       } 
       printf("%I64d\n",ans); 
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值