hdu 5334

题意:给出一个数组的不同子集的个数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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值