spoj SORTBIT - Sorted bit squence

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\n",l);
59     }
60     return 0;
61 }
时间: 2024-10-10 01:11:39

spoj SORTBIT - Sorted bit squence的相关文章

SPOJ 1182 Sorted bit squence

标签(空格分隔): 数位DP 二分 题目链接 先算出答案1的个数,再二分查找 #include<cstdio> #include<cstring> #include<iostream> using namespace std; typedef long long ll; ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}

SPOJ 1182 Sorted bit sequence

题目链接 题意: 分析: 其实如果会了Ural 1057. Amount of Degrees那道题目,这道题自然也就会了... 我们考虑枚举第$k$个数字的$1$的个数,那么我们需要计算的也就是区间内二进制状态下$1$的个数为$x$的数字个数,这个的求法在上一题中写过了... 我们求到第$k$的数字的$1$的个数为$x$,那么我们去二分这个数字是什么,也就是说我们要求一个最靠左的右端点,使得区间$[n,ans]$内$1$的个数为$x$的数字个数恰好为$k$,然后总体思路就解决了... 细节方面

[转] POJ数学问题

转自:http://blog.sina.com.cn/s/blog_6635898a0100magq.html 1.burnside定理,polya计数法 这个大家可以看brudildi的<组合数学>,那本书的这一章写的很详细也很容易理解.最好能完全看懂了,理解了再去做题,不要只记个公式. *简单题:(直接用套公式就可以了) pku2409 Let it Bead      http://acm.pku.edu.cn/JudgeOnline/problem?id=2409 pku2154 Co

『转』数学专辑

1.burnside定理,polya计数法 这个大家可以看brudildi的<组合数学>,那本书的这一章写的很详细也很容易理解.最好能完全看懂了,理解了再去做题,不要只记个公式. *简单题:(直接用套公式就可以了) pku2409 Let it Bead   http://acm.pku.edu.cn/JudgeOnline/problem?id=2409 pku2154 Color http://acm.pku.edu.cn/JudgeOnline/problem?id=2154 pku12

ACM数学(转)

从放暑假前周sir给我讲了一个用polya计数法和burnside定理做的题目(pku2409)后,突然觉得组合数学挺有意思,然后从那时起到现在几乎都在做这类的题目. 做到现在感觉这类题目的一些基本知识点都差不多有所了解了,水题也刷了不少,但还有很多难题自己实在是做不动,所以准备把这类题目先放一放,然后把前段时间做的水题整理一下(供以后的初学者参考,大牛就不要看了哈,都是水题).剩下的比较难的题目就慢慢来吧,以后做出来再不上,这个小结会不断地更新.也希望大家有好的题目可以推荐一下,分享一下哈.

POJ【数论/组合/博弈论】

 POJ[数论/组合/博弈论]题目列表 POJ[数论/组合/博弈论]题目列表 原来的列表比较水,今天换了一个难一些的列表,重新开始做~ 红色的代表已经AC过,蓝色的代表做了但是还没过.这句话貌似在我空间里的每份列表里都有额. 博弈论 POJ 2234 Matches Game POJ 2975 Nim POJ 2505 A multiplication game POJ 1067 取石子游戏 POJ 2484 A Funny Game POJ 2425 A Chess Game POJ 29

poj数论(转)

1.burnside定理,polya计数法    这个大家可以看brudildi的<组合数学>,那本书的这一章写的很详细也很容易理解.最好能完全看懂了,理解了再去做题,不要只记个公式.    *简单题:(直接用套公式就可以了)    pku2409 Let it Bead       pku2154 Color    pku1286 Necklace of Beads    *强烈推荐:(这题很不错哦,很巧妙)    pku2888 Magic Bracelet2.置换,置换的运算 置换的概念

数论专题(转)

经过长时间的试验,发现果然学编程还是要学好数学先,数学引发的更加有质的变化,而盲目学各种编程语言也不能获得一种不一样的体验,或者我没掌握到诀窍.另外打算从这学期学的 信安数学基础 学到的庞大的数论体系开刀,上了这课明显体会到彻底自学就是扯蛋. 网上找到这份题目,还不错的赶脚,刷起! 2014-11-11开始刷起,有链接表示KO 博弈论POJ 2234 Matches GamePOJ 2975 NimPOJ 2505 A multiplication gamePOJ 1067 取石子游戏POJ 2

spoj GCJ1C09C Bribe the Prisoners

题目链接: http://www.spoj.com/problems/GCJ1C09C/ 题意: In a kingdom there are prison cells (numbered 1 to P) built to form a straight line segment. Cells number i and i+1 are adjacent, and prisoners in adjacent cells are called "neighbours." A wall wi