codeforces807div2 E.Prairie Partition[二分]
来源:互联网 发布:淘宝网物流单号 编辑:程序博客网 时间:2024/05/22 15:43
It can be shown that any positive integer x can be uniquely represented as x = 1 + 2 + 4 + ... + 2k - 1 + r, where k and r are integers, k ≥ 0, 0 < r ≤ 2k. Let's call that representation prairie partition of x.
For example, the prairie partitions of 12, 17, 7 and 1 are:
17 = 1 + 2 + 4 + 8 + 2,
7 = 1 + 2 + 4,
1 = 1.
Alice took a sequence of positive integers (possibly with repeating elements), replaced every element with the sequence of summands in its prairie partition, arranged the resulting numbers in non-decreasing order and gave them to Borys. Now Borys wonders how many elements Alice's original sequence could contain. Find all possible options!
The first line contains a single integer n (1 ≤ n ≤ 105) — the number of numbers given from Alice to Borys.
The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 1012; a1 ≤ a2 ≤ ... ≤ an) — the numbers given from Alice to Borys.
Output, in increasing order, all possible values of m such that there exists a sequence of positive integers of length m such that if you replace every element with the summands in its prairie partition and arrange the resulting numbers in non-decreasing order, you will get the sequence given in the input.
If there are no such values of m, output a single integer -1.
81 1 2 2 3 4 5 8
2
61 1 1 2 2 2
2 3
51 2 4 4 4
-1
In the first example, Alice could get the input sequence from [6, 20] as the original sequence.
In the second example, Alice's original sequence could be either [4, 5] or [3, 3, 3].
题意:
一个整数可以拆分成2的幂次加一个尽可能小的常数,现给出一堆数字拆分的结果,问原来可能是几个数字拆来的。
思路:
原来数字的个数一定会小于等于拆分后1的个数。
如果原来可以由n个数字拆分得到,则一定也可以通过m个数字拆分得到(直接凑1),其中 n<m<=1的个数
所以只需要找到最小能拆分成几个即可。 且范围在1 到 pownum[0]之间,可以直接二分个数。
首先预处理记录2的幂次的个数到pownum[i], 2的i次幂与i+1次幂之间有多少个数字记录到betnum[i]
对于每一种拆分个数,针对当前链路进行操作,发生断链则进行相应操作,详细代码注释。
#include<bits/stdc++.h>using namespace std;typedef long long LL;LL n;int pownum[2005]; //pownum[i]表示2的i次方有多少个int betnum[2005]; //betnum[i]表示大于2的i次幂小于2的i+1次幂的个数int check(LL x){ //x表示当前的可更新的链的个数,初始一定为x,即总个数 LL t = pownum[0] - x; // 多余的1的个数 for(int i = 1; i < 64; ++i) { if(x >= pownum[i]) { t -= min(t, x-pownum[i]); x = pownum[i]; } else t += pownum[i]-x; t += betnum[i]; } return t<=x;}int main(){ ios::sync_with_stdio(false); cin >> n; LL x; for(int i = 0; i < n; ++i) { cin >> x; bool flag = 1; int id = 0; while(x>1) { if(x&1) // x不是2的幂次 flag = 0; id++; x >>= 1; } if(flag) pownum[id]++; else betnum[id]++; } LL ans = -1, l = 1, r = pownum[0]; //二分个数, 最大为2^0的个数 while(l <= r) { LL mid = (l+r) >> 1; if(check(mid)) { ans = mid; r = mid - 1; } else l = mid + 1; } if(ans == -1) { cout << ans << endl; } else for(int i = ans; i <= pownum[0]; ++i) { cout << i << " "; } return 0;}
- codeforces807div2 E.Prairie Partition[二分]
- Codeforces 807E Prairie Partition 贪心思维+二分
- CF806C:Prairie Partition(二分)
- Codeforces Round #412-E-Prairie Partition
- codeforces807div2 C.Success Rate[二分][数学]
- E简单二分查找
- 二分贪心专题E
- 二分贪心 E
- 二分贪心 E
- 二分贪心 E题
- 二分贪心—E
- 二分贪心-E
- 二分贪心e
- world final2017-E 二分
- TOJ:Prairie dogs
- 【二分+染色】集合划分(Partition)
- Partition List 二分链表(重)
- leetcode Partition List二分链表问题
- 十个主题,最全的优秀 TensorFlow 相关资源列表
- Linux虚拟机的网络配置 linux 用户的设置。
- 1046. 划拳(15)
- Android mvp兼职平台小项目《SmallExcellent》
- Dash Speed
- codeforces807div2 E.Prairie Partition[二分]
- 彻底删除visual stdio
- 【python学习笔记】9:用k-means算法对数据进行聚类
- MySQL优化系列(二)--查找优化(2)(外连接、多表联合查询以及查询注意点)
- NOIP2016全国信息学分区普级组 买铅笔(c++版)
- 资源 | 数十种TensorFlow实现案例汇集:代码+笔记
- Volley与Retrofit(OKHttp)使用与区别
- 字符串
- 电机矢量控制中采样周期应该如何定