zoukankan      html  css  js  c++  java
  • 【spoj1182/usaco-Cow Queueing, 2003 Dec-二进制编号】数位dp

    题意:定义新的排序:先按一个数中二进制中1的个数从小到大排序,如果1的个数相同则按数的大小从小到大排序。问[A,B]之间有第K大的数是哪个。-2^31<=A,B<=2^31(A,B必定同正负,负数的二进制与它相反数的二进制相加=2^32)

    题解:

    负数可以直接+2^31-1转化为正数。

    先确定答案中1的个数:依次统计区间[m,n]内二进制表示中含1的数量为0,1,2,…的数,直到累加的答案超过k,则当前值就是答案含1的个数,假设是ind。

    怎么求?就先确定当前位填什么,然后后面还有多少个1可以填,组合数弄一下。

    同时,我们也求出了答案是第几个[m,n]中含ind个1的数。因此,只需二分答案,求出[m,ans]中含s个1 的数的个数进行判断即可。

    这个二分需要不断往左端点靠,假设答案是ans,ans+1也含有跟ans一样的还有ind个1的数的个数。

     

     

    spoj1182(输入是十进制)

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<iostream>
     6 #include<algorithm>
     7 using namespace std;
     8 
     9 typedef long long LL;
    10 const int N=50;
    11 const LL MX=(1LL<<32);
    12 LL X,Y,K,c[N][N];
    13 
    14 void myswap(LL &x,LL &y){LL t;t=x;x=y;y=t;return;}
    15 
    16 void find_c()
    17 {
    18     memset(c,0,sizeof(c));
    19     c[0][0]=1;
    20     for(int i=1;i<=35;i++)
    21     {
    22         c[i][0]=1;
    23         for(int j=1;j<=i;j++) c[i][j]=c[i-1][j]+c[i-1][j-1];
    24     }
    25 }
    26 
    27 LL find_k(LL x,int ind,int k)//0~x how many numbers has k '1's;
    28 {
    29     if(ind==0 && k==0) return 1;
    30     if(x<0 || ind==0 || k<0) return 0;
    31     LL t=1LL<<(ind-1);
    32     if(x&t) return c[ind-1][k]+find_k(x,ind-1,k-1);
    33     else return find_k(x,ind-1,k);
    34 }
    35 
    36 int main()
    37 {
    38     freopen("a.in","r",stdin);
    39     // freopen("me.out","w",stdout);
    40     int T;
    41     scanf("%d",&T);
    42     find_c();
    43     while(T--)
    44     {
    45         scanf("%lld%lld%lld",&X,&Y,&K);
    46         if(X<0) X=MX+X;
    47         if(Y<0) Y=MX+Y;
    48         if(X>Y) myswap(X,Y);
    49         
    50         LL sum=0,ind=0,now,k;
    51         for(int i=0;i<=31;i++)
    52         {
    53             now=find_k(Y,32,i)-find_k(X-1,32,i);
    54             if(sum+now<K) sum+=now,ind=i;
    55             else {k=K-sum;break;}
    56         }
    57         ind++;
    58         // printf("ind = %lld k = %lld
    ",ind,k);
    59         LL l=X,r=Y,mid;
    60         while(l<r)
    61         {
    62             mid=(l+r)/2;
    63             now=find_k(mid,32,ind)-find_k(X-1,32,ind);
    64             // printf("mid = %lld  now = %lld  %lld
    ",mid,now,find_k(mid,32,ind));
    65             if(now<k) l=mid+1;
    66             else r=mid;
    67         }
    68         printf("%d
    ",l);
    69         
    70     }
    71     return 0;
    72 }

    usaco (usaco上输入输出都是二进制形式)

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<iostream>
     6 #include<algorithm>
     7 using namespace std;
     8 
     9 typedef long long LL;
    10 const int N=50;
    11 const LL MX=(1LL<<32);
    12 LL X,Y,K,c[N][N],d[N],bit[N];
    13 char s[20];
    14 
    15 void myswap(LL &x,LL &y){LL t;t=x;x=y;y=t;return;}
    16 
    17 void find_c()
    18 {
    19     memset(c,0,sizeof(c));
    20     c[0][0]=1;
    21     for(int i=1;i<=35;i++)
    22     {
    23         c[i][0]=1;
    24         for(int j=1;j<=i;j++) c[i][j]=c[i-1][j]+c[i-1][j-1];
    25     }
    26 }
    27 
    28 LL find_k(LL x,int ind,int k)//0~x how many numbers has k '1's;
    29 {
    30     if(ind==0 && k==0) return 1;
    31     if(x<0 || ind==0 || k<0) return 0;
    32     LL t=1LL<<(ind-1);
    33     if(x&t) return c[ind-1][k]+find_k(x,ind-1,k-1);
    34     else return find_k(x,ind-1,k);
    35 }
    36 
    37 LL read()
    38 {
    39     scanf("%s",s);
    40     LL x=0;int l=strlen(s);
    41     for(int i=l-1;i>=0;i--)
    42     {
    43         if(s[i]=='1') x+=bit[l-i-1];
    44     }
    45     return x;
    46 }
    47 
    48 int main()
    49 {
    50     // freopen("a.in","r",stdin);
    51     freopen("cowq.in","r",stdin);
    52     freopen("cowq.out","w",stdout);
    53     find_c();
    54     bit[0]=1;
    55     for(int i=1;i<=31;i++) bit[i]=bit[i-1]*2;
    56     
    57     X=read();
    58     Y=read();
    59     scanf("%lld",&K);
    60     // printf("X = %lld  Y = %lld
    ",X,Y);
    61     // scanf("%lld",&X,&Y,&K);
    62     if(X<0) X=MX+X;
    63     if(Y<0) Y=MX+Y;
    64     if(X>Y) myswap(X,Y);
    65         
    66     LL sum=0,ind=0,now,k;
    67     for(int i=0;i<=31;i++)
    68     {
    69         now=find_k(Y,32,i)-find_k(X-1,32,i);
    70         if(sum+now<K) sum+=now,ind=i;
    71         else {k=K-sum;break;}
    72     }
    73     ind++;
    74     // printf("ind = %lld  k = %lld
    ",ind,k);
    75     LL l=X,r=Y,mid,p=find_k(X-1,32,ind);
    76     while(l<r)
    77     {
    78         mid=(l+r)/2;
    79         now=find_k(mid,32,ind)-p;
    80         // if(now<k) l=mid+1;
    81         if(now<k) l=mid+1;
    82         if(now>=k) r=mid;
    83     }
    84     // printf("%d
    ",l);
    85     int x=0;
    86     while(l)
    87     {
    88         d[++x]=l%2;
    89         l/=2;
    90     }
    91     for(int i=x;i>=1;i--) printf("%d",d[i]);printf("
    ");
    92     return 0;
    93 }

     

     

  • 相关阅读:
    vue项目进行时,script标签中,methods事件中函数使用的async/await
    css阴影——box-shadow
    vue报错——Module not found: Error: Can't resolve 'less-loader sass' in ...
    vue组件如何引入外部.js/.css/.scss文件
    获得汉字的拼音或者拼音简写
    model转XML
    sql server 添加表注释、字段注释
    (转)SQL Server 监控统计阻塞脚本信息
    系统首页右下角弹框
    DropDownListExtend控件
  • 原文地址:https://www.cnblogs.com/KonjakJuruo/p/6021972.html
Copyright © 2011-2022 走看看