码迷,mamicode.com
首页 > 其他好文 > 详细

HDU5661 Claris and XOR

时间:2017-10-13 14:15:52      阅读:139      评论:0      收藏:0      [点我收藏+]

标签:long   题意   +=   效果   size   --   需要   mda   log   

我们求二进制是怎么求的呢:先看看二进制的每一位代表多大:.......32 16 8 4 2 1

 假如n=10

                   .....

                  32>n ,不要。

                 16>n,不要。

                  8<=n,要,然后n=n-8=2。

                  4>2,不要。

                  2<=2,要,n=n-2=0;

                  0>1,不要。

不要是一位是0,要的一位是1,则10(10)=..001010(2),也就是从高位向低位求,能取则取

 

题意:现在对对于这个题,求a<=x<=b,c<=y<=d,使x^y最大(不同位数最多)。

 

我们来试一试搜索:数量级差不多再1<<60左右,我们设62位为最高位。

对于x,第i位有0或1的选择。对于y,第i位也有0或1的选择,则搜索的数量级位(2^120),爆炸。但是由于取1可能会有x>b,取0会有x<a,取什么对x是有限定的,即是搜索的减枝,这使得数量级不会太大。所以我们开始搜索,当然,搜索的方向是对于第i位,二者尽量取不同,即在满足[a,b],[c,d]的范围内一个取0,一个取1。如果不行,则二者同取1或取0(效果一样,就当a,b,c,d同时减去0或者同时减去1<<i)。————>然后发现这个搜索不需要回溯,根本就是个贪心。

 

如何给予限定:假设x在第i+1位取得t1,在第i位,如果t1+(1LL<<i)>b则不能取1,如果t1+(1LL<<i)-1<a,则不能取0。(iLL<<i)-1表示第i位不取,1-(i-1)都取。

 

int            1<<i

long long 1LL<<i

HDU5661
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cmath>
using namespace std;
long long  a,b,c,d,x,y,t1,t2,ans;
int main()
{
    long long i,j,T;
    scanf("%lld",&T);
    while(T--){
        ans=x=y=0;
        scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
        for(i=62;i>=0;i--){
             t1=x+(1LL<<i);t2=y+(1LL<<i);
             if(t1<=b&&t2-1>=c) {
                    x=t1;ans+=(1LL<<i);
             }
             else if(t2<=d&&t1-1>=a){
                    y=t2;ans+=(1LL<<i);
             }
             else if(t1-1>=a&&t2-1>=c){
                    continue;
             }
             else if(t1<=b&&t2<=d){
                    x=t1;y=t2;
             }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

HDU5661 Claris and XOR

标签:long   题意   +=   效果   size   --   需要   mda   log   

原文地址:http://www.cnblogs.com/hua-dong/p/7660322.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!