hdu 5334

来源:互联网 发布:anaconda for mac 编辑:程序博客网 时间:2024/06/05 14:34

题意:给出一个数组的不同子集的个数k,求出一个数列满足这个条件;

思路:当数列为1 ,2,3,,,,n的时候,不同子集的个数就为等差数列求和n * (n + 1)/2;当数列中出现两个相同的数的时候,你会发现不同子集数少了一个,

以此类推,3个的时候少了 1+ 2 = 3个,4个的时候少了1 + 2 + 3个……;


找的时候记得用二分;


#include<bits/stdc++.h>using namespace std;const int maxn = 100000 + 10;typedef long long ll;ll a[maxn];void Init(){a[1] = 1;for(int i = 2; i < maxn; i ++){a[i] = a[i - 1] + i;}}int n,m;int num[maxn];int main(){int Tcase;Init();//cout << a[16] << endl;//scanf("%d",&Tcase);while( ~ scanf("%d",&n))//while( ~ scanf("%d%d",&n,&m)){int pos = lower_bound(a+1,a+maxn,n) - a;if(a[pos] == n){cout << pos << endl;for(int i = 1; i <= pos; i ++){if(i == pos)cout << i << endl;else cout << i << " ";}continue;}while(true){ll t = a[pos] - n;int len = pos;int lens = 0;while(t){int poss = lower_bound(a+1,a+maxn,t) - a;if(a[poss] == t){num[lens ++] = poss + 1;//cout << poss << " " << num[lens - 1] << endl;len -= (poss + 1);break;}else{t -= a[poss - 1];num[lens ++] = poss;//cout << poss -1  << " " << num[lens - 1] << endl;len -= (poss);}}if(len < 0){pos ++;continue;}//cout << pos << endl;//int ans = a[pos];//for(int i = 0; i < lens; i ++)//{//cout << num[i] << " ";//ans -= a[num[i] - 1];//}cout << "ps" << endl;//cout << "II" <<ans << endl;cout << pos << endl;for(int i = 1; i <= len; i ++){cout << i << " ";}for(int i = 0,t = len + 1,k = len + 1; i < lens; i ++,t ++){while(num[i] --){if(k < pos)cout << t << " ";else cout << t << endl;k ++; }}break;}}return 0;}


0 0