• 四校联考(20170910)


    ditoly出的题目果然丧,待我一天啃一题。。。。。

    废话不多说,开更:

    ————————————————————我是分割线——————————————————

    T1:最大值(max)

    【问题描述】

    C有n个区间,其中第i个区间为[li,ri],小C想从每个区间中各选出一个整数,使得所有选出的数and起来得到的结果最大,请你求出这个值。

    【输入格式】

    第一行一个正整数n,表示区间个数。

    接下来n行,每行两个非负整数li,ri。

    【输出格式】

    输出一个整数,表示答案。

    【样例输入】

    2

    1 3

    4 6

    【样例输出】

    2

    【数据范围】

    对于数据点1~2,sum(ri-li+1)(1<=i<=n)不超过10^7

    对于数据点3~4,存在一个x满足对于每个区间,li<=x<=ri

    对于数据点5~6n=2

    对于数据点7~8ri<=10^5

    对于全部数据(1~10),n<=10^5li<=ri<=10^18

    ————————————————————我是分割线——————————————————

    神奇题目emmmmm

    我们先要明白一个事情,那就是假如说我们从大到小枚举i,如果所有的区间在二进制下第i位都可以取到1,那么显然这个1一定作为答案

    那么我们怎么处理接下来的区间呢?

    我们分情况讨论,假如说所有的区间在目前的第i位都可以取到i,那么枚举每一个区间,假如目前区间的左端点不能取到1,那么我们就把li赋值为0,因为我们的判断是靠ri判断的,不影响答案。表示我们后面的数都可以取到0,而这样做可以证明不会使答案变得更劣。

    那么如果不能满足所有的区间都取到1,那么我们继续分情况讨论:

    如果所有的区间这一位都只能取到0,那么就取0

    否则如果有的区间可以取0,有的区间可以取1,那么我们显然取0,因为取1&之后还是0,而取0之后1~i-1位都可以取1,一定最优。所以我们把满足这种条件的区间的右端点设为(1<<i)-1

    然后就是贴代码啦!

    #include<cstdio>
    #define MN 100005
    long long l[MN],r[MN],ans;
    int main()
    {
        freopen("max.in","r",stdin);
        freopen("max.out","w",stdout);
        int n,i,j;
        scanf("%d",&n);
        for(i=1;i<=n;++i)scanf("%I64d%I64d",&l[i],&r[i]);
        for(i=60;i--;)
        {
            for(j=1;j<=n;++j)if(!(r[j]&(1LL<<i)))break;
            if(j>n)for(ans+=1LL<<i,j=1;j<=n;++j){if(!(l[j]&(1LL<<i)))l[j]=0;}
            else for(j=1;j<=n;++j)if((l[j]&(1LL<<i))!=(r[j]&(1LL<<i)))r[j]=(1LL<<60)-1;
        }
        printf("%lld
    ",ans);
        fclose(stdin);
        fclose(stdout);
    }

    ————————————————————我是分割线——————————————————

  • 相关阅读:
    Hello_Area_Description 任务三:Project Tango采集区域描述数据
    智能小车 机器人
    Hello_Depth_Perception 任务二:Project Tango采集深度感知数据
    Project Tango Explorer
    make运行阶段划分
    关于chroot
    xargs命令
    debian配置集锦
    gdb使用技巧
    gdb调试使用autotools工程的项目
  • 原文地址:https://www.cnblogs.com/ghostfly233/p/7505982.html
Copyright © 2020-2023  润新知