开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第34天,点击查看活动详情
AcWing——4787. 构造序列
4787. 构造序列 - AcWing题库
对于一个长度为 nn 的正整数序列 a1,a2,…,ana1,a2,…,an,我们这样规定该序列的价值:
- 如果 nn 为偶数,则序列价值为 gcd(a1,a2)+gcd(a3,a4)+…+gcd(an−1,an)gcd(a1,a2)+gcd(a3,a4)+…+gcd(an−1,an)。
- 如果 nn 为奇数,则序列价值为 gcd(a1,a2)+gcd(a3,a4)+…+gcd(an−2,an−1)gcd(a1,a2)+gcd(a3,a4)+…+gcd(an−2,an−1)。
请你构造一个长度为 n 的正整数序列 a1,a2,…,an,要求:
- ai 两两不同。
- 1≤ai≤10^9。
- 序列价值恰好为 m。
输入格式
共一行,两个整数 n,m。
输出格式
共一行,如果序列不存在,则输出 -1,否则输出 a1,a2,…,an。
如果答案不唯一,输出任意合理答案均可。
数据范围
前 77 个测试点满足 1≤n≤10。 所有测试点满足 1≤n≤10^5,0≤m≤10^8。
输入样例1:
5 2
输出样例1:
1 2 3 4 5
问题解析
首先,因为最小的gcd是1,所以长度为n的数组,它的最小gcd之和应该是n/2,如果m小于这个,就输出-1。当n=1时,如果m不是0,也输出-1.
然后就像我们说的,最小的gcd是1,那么最简单的构造方法就是,我们用n-2个数来构造数组,提供(n-2)/2个gcd为1的数对,再用剩下的两个数构造出缺少的数即可。
AC代码
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include <random>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<fstream>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
#include<bitset>
//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
#define endl '\n'
#define int ll
#define PI acos(-1)
#define INF 0x3f3f3f3f
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 2e5 + 50, MOD = 998244353;
int a[N];
void solve()
{
int n, m;
cin >> n >> m;
if ((n==1&&m!=0)||n / 2 > m)
{
cout << -1 << endl;
return;
}
int cnt = (n - 2) / 2;
int ans = m - cnt;
if (ans > 0)cout << ans << " " << ans * 2 << " ";
int num = ans * 2 + 1;
for (int i = 1; i <= cnt; i++)
{
cout << num++ << " " << num++ << " ";
}
if (n % 2 == 1)cout << num << endl;
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t = 1;
//cin >> t;
while (t--)
{
solve();
}
return 0;
}