zoukankan      html  css  js  c++  java
  • spoj SORTBIT

    Let's consider the 32 bit representation of all integers i from m up to n inclusive (m ≤ i ≤ n; m × n ≥ 0, -2^31 ≤ m ≤ n ≤ 2^31-1). Note that a negative number is represented in 32 bit Additional Code. That is the 32 bit sequence, the binary sum of which and the 32 bit representation of the corresponding positive number is 2^32 (1 0000 0000 0000 0000 0000 0000 0000 0000 in binary).

    For example, the 32 bit representation of 6 is 0000 0000 0000 0000 0000 0000 0000 0110

    and the 32 bit representation of -6 is 1111 1111 1111 1111 1111 1111 1111 1010

    because

    0000 0000 0000 0000 0000 0000 0000 0110 (6) 

    1111 1111 1111 1111 1111 1111 1111 1010 (-6) 
    -------------------------------------------------
    = 1 0000 0000 0000 0000 0000 0000 0000 0000 (2^32)

    Let's sort the 32 bit representations of these numbers in increasing order of the number of bit 1. If two 32 bit representations that have the same number of bit 1, they are sorted in lexicographical order.

    For example, with m = 0 and n = 5, the result of the sorting will be

    No.

    Decimal number

    Binary 32 bit representation

    1

    0

    0000 0000 0000 0000 0000 0000 0000 0000

    2

    1

    0000 0000 0000 0000 0000 0000 0000 0001

    3

    2

    0000 0000 0000 0000 0000 0000 0000 0010

    4

    4

    0000 0000 0000 0000 0000 0000 0000 0100

    5

    3

    0000 0000 0000 0000 0000 0000 0000 0011

    6

    5

    0000 0000 0000 0000 0000 0000 0000 0101

    with m = -5 and n = -2, the result of the sorting will be

    No.

    Decimal number

    Binary 32 bit representation

    1

    -4

    1111 1111 1111 1111 1111 1111 1111 1100

    2

    -5

    1111 1111 1111 1111 1111 1111 1111 1011

    3

    -3

    1111 1111 1111 1111 1111 1111 1111 1101

    4

    -2

    1111 1111 1111 1111 1111 1111 1111 1110

     

    Given m, n and k (1 ≤ k ≤ min{n − m + 1, 2 147 473 547}), your task is to write a program to find a number corresponding to k-th representation in the sorted sequence.

    Input

    The input consists of several data sets. The first line of the input file contains the number of data sets which is a positive integer and is not bigger than 1000. The following lines describe the data sets.

    For each data set, the only line contains 3 integers m, n and k separated by space.

    Output

    For each data set, write in one line the k-th number of the sorted numbers.

    Example

    Sample input:

    2

    0 5 3

    -5 -2 2

    Sample output:

    2

    -5

    题解:

    我们首先考虑 m、n 同正的情况。
    由于排序的第一关键字是 1 的数量,第二关键字是数的大小, 因此我们很容易确定答案
    中 1 的个数:依次统计区间[m,n]内二进制表示中含 1 的数量为 0,1,2,...的数,直到累加的答
    案超过 k,则当前值就是答案含 1 的个数,假设是 s。利用例一的算法可以解决这个问题。
    同时,我们也求出了答案是第几个[m,n]中含 s 个 1 的数。因此,只需二分答案,求出[m,ans]
    中含 s 个 1 的数的个数进行判断即可。
    由于每次询问的复杂度为 O(log(n)),故二分的复杂度为 O(log 2 (n)),这同时也是预处理
    的复杂度,因此此算法较为理想。
    m<0 的情况,也不难处理,我们只要忽略所有数的最高位,求出答案后再将最高位赋回
    1 即可。或者也可以直接将负数视为 32 位无符号数,采用同正数一样的处理方法。两种方
    法都需要特别处理 n=0 的情况。

    code:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 using namespace std;
     7 char ch;
     8 bool ok;
     9 void read(int &x){
    10     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
    11     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    12     if (ok) x=-x;
    13 }
    14 void read(unsigned int &x){
    15     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
    16     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    17     if (ok) x=-x;
    18 }
    19 typedef long long int64;
    20 const int maxn=34;
    21 const int64 inf=1LL<<32;
    22 int T,a,b,s,l,r,m,tmp[maxn];
    23 unsigned int k,x,y,c[maxn][maxn];
    24 void init(){
    25     for (int i=0;i<=32;i++) c[i][0]=1;
    26     for (int i=1;i<=32;i++) for (int j=1;j<=i;j++) c[i][j]=c[i-1][j-1]+c[i-1][j];
    27 }
    28 unsigned int calc(int64 n,int k){
    29     int64 t=n;
    30     int len=0,res=0;
    31     unsigned int ans=0;
    32     memset(tmp,0,sizeof(tmp));
    33     while (t) tmp[++len]=t&1,t>>=1;
    34     for (int i=len;i;i--){
    35         if (tmp[i]) ans+=c[i-1][k-res],res++;
    36         if (res>k) break;
    37     }
    38     return ans;
    39 }
    40 unsigned int query(unsigned int l,unsigned int r,int s){
    41     if (l<=r) return calc(r+1LL,s)-calc(l,s);
    42     else return calc(inf,s)-calc(l,s)+calc(r+1LL,s);
    43 }
    44 int main(){
    45     init();
    46     for (read(T);T;T--){
    47         read(a),read(b),read(k);
    48         for (s=0;s<=32;s++){
    49             unsigned int res=query(a,b,s);
    50             if (k>res) k-=res; else break;
    51         }
    52         l=a,r=b;
    53         while (l!=r){
    54             m=(0LL+l+r)>>1;
    55             unsigned int res=query(a,m,s);
    56             if (k>res) l=m+1; else r=m;
    57         }
    58         printf("%d
    ",l);
    59     }
    60     return 0;
    61 }
  • 相关阅读:
    xwalkview 替换掉webview 注意事项
    rsyslog Properties 属性:
    Basic Structure 基本结构:
    Crosswalk 集成到 Android Studio
    awk if 判断
    Important System Configuration 导入系统配置:
    Heap size check 堆大小检查
    Bootstrap Checks 抽样检查:
    Important Elasticsearch configuration 导入Elasticsearch 配置
    while 退出循环
  • 原文地址:https://www.cnblogs.com/chenyushuo/p/5238082.html
Copyright © 2011-2022 走看看