The 2022 ICPC Asia Regionals Online Contest (I) D题

题目传送门
在这里插入图片描述

题意:
定义一种合法的数字:其二进制数的末尾0的个数与所有1的个数相同。给定q组询问,每组询问给出一个区间[l,r],找出这个区间内是否存在这样合法的数字。
思路:
做法离大谱(非正常思路,脑子有坑),本题主要是统计出1e9内的所有合法数字,不会数位dp的我只能另寻他法。

思路如下:
C 0 28  10
C 1 27  100
C 2 26  1000
C 3 25  10000
C 4 24  100000
C 5 23  ...
C 6 22
C 7 21
C 8 20
C 9 19
C 10 18 = C 8 18
C 11 17 = C 6 17
C 12 16 = C 4 16
C 13 15 = C 2 15
C 14 14 = 1

#include<iostream>
#include<algorithm>
using namespace std;

int t;
long long arr[1000000];
int k;
int M=1073741824;

void init() // 按1的个数枚举出所有可能的结果,不重不漏
{
    //28
    arr[k++]=2;
    //27
    for(int i1=3;i1<30;i1++)
        arr[k++]=(1<<2)+(1<<i1);
    //26
    for(int i1=4;i1<29;i1++)
        for(int i2=i1+1;i2<30;i2++)
            arr[k++]=(1<<3)+(1<<i1)+(1<<i2);
    //25
    for(int i1=5;i1<28;i1++)
        for(int i2=i1+1;i2<29;i2++)
            for(int i3=i2+1;i3<30;i3++)
                arr[k++]=(1<<4) + (1<<i1) + (1<<i2) + (1<<i3);
    //24
    for(int i1=6;i1<27;i1++)
        for(int i2=i1+1;i2<28;i2++)
            for(int i3=i2+1;i3<29;i3++)
                for(int i4=i3+1;i4<30;i4++)
                    arr[k++]=(1<<5) + (1<<i1) + (1<<i2) + (1<<i3) + (1<<i4);
    //23
    for(int i1=7;i1<26;i1++)
        for(int i2=i1+1;i2<27;i2++)
            for(int i3=i2+1;i3<28;i3++)
                for(int i4=i3+1;i4<29;i4++)
                    for(int i5=i4+1;i5<30;i5++)
                        arr[k++]=(1<<6) + (1<<i1) + (1<<i2) + (1<<i3) + (1<<i4) + (1<<i5);
    //22
    for(int i1=8;i1<25;i1++)
        for(int i2=i1+1;i2<26;i2++)
            for(int i3=i2+1;i3<27;i3++)
                for(int i4=i3+1;i4<28;i4++)
                    for(int i5=i4+1;i5<29;i5++)
                        for(int i6=i5+1;i6<30;i6++)
                            arr[k++]=(1<<7) + (1<<i1) + (1<<i2) + (1<<i3) + (1<<i4) + (1<<i5) + (1<<i6);
    //21
    for(int i1=9;i1<24;i1++)
        for(int i2=i1+1;i2<25;i2++)
            for(int i3=i2+1;i3<26;i3++)
                for(int i4=i3+1;i4<27;i4++)
                    for(int i5=i4+1;i5<28;i5++)
                        for(int i6=i5+1;i6<29;i6++)
                            for(int i7=i6+1;i7<30;i7++)
                                arr[k++]=(1<<8) + (1<<i1) + (1<<i2) + (1<<i3) + (1<<i4) + (1<<i5) + (1<<i6) + (1<<i7);
    //20
    for(int i1=10;i1<23;i1++)
        for(int i2=i1+1;i2<24;i2++)
            for(int i3=i2+1;i3<25;i3++)
                for(int i4=i3+1;i4<26;i4++)
                    for(int i5=i4+1;i5<27;i5++)
                        for(int i6=i5+1;i6<28;i6++)
                            for(int i7=i6+1;i7<29;i7++)
                                for(int i8=i7+1;i8<30;i8++)
                                    arr[k++]=(1<<9) + (1<<i1) + (1<<i2) + (1<<i3) + (1<<i4) + (1<<i5) + (1<<i6) + (1<<i7) + (1<<i8);
    //19
    for(int i1=11;i1<22;i1++)
        for(int i2=i1+1;i2<23;i2++)
            for(int i3=i2+1;i3<24;i3++)
                for(int i4=i3+1;i4<25;i4++)
                    for(int i5=i4+1;i5<26;i5++)
                        for(int i6=i5+1;i6<27;i6++)
                            for(int i7=i6+1;i7<28;i7++)
                                for(int i8=i7+1;i8<29;i8++)
                                    for(int i9=i8+1;i9<30;i9++)
                                        arr[k++]=(1<<10) + (1<<i1) + (1<<i2) + (1<<i3) + (1<<i4) + (1<<i5) + (1<<i6) + (1<<i7) + (1<<i8) + (1<<i9);
    //18
    for(int i1=12;i1<23;i1++)
        for(int i2=i1+1;i2<24;i2++)
            for(int i3=i2+1;i3<25;i3++)
                for(int i4=i3+1;i4<26;i4++)
                    for(int i5=i4+1;i5<27;i5++)
                        for(int i6=i5+1;i6<28;i6++)
                            for(int i7=i6+1;i7<29;i7++)
                                for(int i8=i7+1;i8<30;i8++)
                                    arr[k++]=M-(1<<11)-((1<<i1) + (1<<i2) + (1<<i3) + (1<<i4) + (1<<i5) + (1<<i6) + (1<<i7) + (1<<i8));
    //17
    for(int i1=13;i1<25;i1++)
        for(int i2=i1+1;i2<26;i2++)
            for(int i3=i2+1;i3<27;i3++)
                for(int i4=i3+1;i4<28;i4++)
                    for(int i5=i4+1;i5<29;i5++)
                        for(int i6=i5+1;i6<30;i6++)
                            arr[k++]=M-(1<<12)-((1<<i1) + (1<<i2) + (1<<i3) + (1<<i4) + (1<<i5) + (1<<i6));
    //16
    for(int i1=14;i1<27;i1++)
        for(int i2=i1+1;i2<28;i2++)
            for(int i3=i2+1;i3<29;i3++)
                for(int i4=i3+1;i4<30;i4++)
                    arr[k++]=M-(1<<13)-((1<<i1) + (1<<i2) + (1<<i3) + (1<<i4));

    //15
    for(int i1=15;i1<29;i1++)
        for(int i2=i1+1;i2<30;i2++)
            arr[k++]=M-(1<<14)-((1<<i1) + (1<<i2));
    //14
    arr[k++]=M-(1<<15);
}

int main()
{
    cin>>t;
    int a,b;
    init();
    sort(arr,arr+k);
    while(t--)
    {
        scanf("%d %d",&a,&b);
        int l=0,r=k;
        while(l<r)
        {
            int mid=(l+r)/2;
            if(arr[mid]>=a) r=mid;
            else l=mid+1;
        }
        if(arr[l]<=b) cout<<arr[l]<<endl;
        else cout<<-1<<endl;
    }
    return 0;
}
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

勇敢nn

心动不如行动,感谢您的支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值