Divide by Zero 2018 and Codeforces Round #474 (Div. 1 + Div. 2, combined)
题意
构造一个序列,其子序列中满足 m a x − m i n > = d max - min >= d max−min>=d的数量为x。
思路
Let’s call a subsequence valid if the difference of maximum element and minimum element is less than d.
~
For an array of size n with all the elements equal, there are 2n - 1 non-empty subsequences and all of them are valid. This is because for any subsequence, the difference of maximum element and minimum element is always zero.
~
We will use this observation in constructing the answer. Let’s look at the binary representation of X. If the ith bit is set in X, we will add i equal elements (let’s say y) in our final array. However this would give us 2i - 1 non-empty valid subsequences. To correct this, we will add a separate element y + d in the final array so that the final contribution of ith bit becomes 2i. We will carry out the same process for all the bits, keeping a counter of the previous.
~
In this way, the length of the final array will never exceed 600 elements.Expected Complexity : O(logX * logX)
任意一个含有n个相同的数的序列,其满足条件的子序列个数为 2 n − 1 2^n-1 2n−1。所以可以用二进制拆分的思想,将x进行拆分。每次求出一个满足条件 2 n − 1 ≤ x 2^n - 1 \le x 2n−1≤x 的整数n。初次在数组中加入n个1,之后每次加入的数都增加d。这样便可保证数组中最大的数尽量小。且题目数据范围内均有解。
#include<cstdio>
#include<queue>
#include<set>
#include<cstdlib>
#include<string.h>
#include<string>
#include<iostream>
#include<cmath>
#include<unordered_map>
#include<map>
#include<algorithm>
#define endl "\n"
#define IOS ios::sync_with_stdio(0), cin.tie(0),cout.tie(0)
#define ft first
#define sd second
#define pll pair<ll, ll>
#define pii pair<int, int>
#define ll long long int
#define ull unsigned long long int
#define mt(a,b) memset(a, b, sizeof a)
//#define int long long
const double PI = acos(-1.0);
const int inf = 0x3f3f3f3f;
const int INF = 0x7fffffff;
using namespace std;
const int N = 2e5 + 7, M = 1e6 + 10;
ll a[N], b[N];
int main()
{
IOS;
ll x, d; cin >> x >> d;
ll k = 0, start = 1;
while (x)
{
int t = log(x + 1) / log(2);
for(int i = 1; i <= t; i++)
{
a[++k] = start;
}
x -= (ll)pow(2, t) - 1;
start += d;
}
if (k > 40000) cout << -1 << endl;//可有可无
else
{
cout << k << endl;
for (int i = 1; i <= k; i++)
cout << a[i] << " ";
}
return 0;
}