CF1497C1 k-LCM (easy version)
CF1497C2 k-LCM (hard version)
题意:
给定一个整数 n,请找到 k 个和为 n 的正整数a1,a2,....,aka_1,a_2,....,a_ka1,a2,....,ak,使得lcma1,a2,....,ak<=n2lcm{a_1,a_2,....,a_k}<=\frac{n}{2}lcma1,a2,....,ak<=2n
t组数据,1<=t<=1e4,3<=n<=1e9,3<=k<=n1<=t<=1e4,3<=n<=1e9,3<=k<=n1<=t<=1e4,3<=n<=1e9,3<=k<=n
保证所有t组数据中∑k<=1e5保证所有t组数据中\sum k<=1e5保证所有t组数据中∑k<=1e5
在简单版中k=3,困难版中k∈[3,n]
题解:
本题是构造题,也是规律题,不过我属实没看出来
我们先考虑当k=3时的情况,
当n为奇数时,令这三个数的最小公倍数为⌊n2⌋\lfloor \frac{n}{2} \rfloor⌊2n⌋。则这三个数可以是1,⌊n2⌋\lfloor \frac{n}{2} \rfloor⌊2n⌋,⌊n2⌋\lfloor \frac{n}{2} \rfloor⌊2n⌋。和为n,其最小公倍数<=⌊n2⌋\lfloor \frac{n}{2} \rfloor⌊2n⌋
当n为偶数且n mod 4!=0时,我们令三个数的最小公倍数为⌊n2⌋\lfloor \frac{n}{2} \rfloor⌊2n⌋,则三个数分别是2,⌊n2⌋\lfloor \frac{n}{2} \rfloor⌊2n⌋-1,⌊n2⌋\lfloor \frac{n}{2} \rfloor⌊2n⌋-1
当n为4的倍数时,我们令最小公倍数为⌊n2⌋\lfloor \frac{n}{2} \rfloor⌊2n⌋,则三个数为⌊n2⌋\lfloor \frac{n}{2} \rfloor⌊2n⌋,⌊n4⌋\lfloor \frac{n}{4} \rfloor⌊4n⌋,⌊n4⌋\lfloor \frac{n}{4} \rfloor⌊4n⌋
这个三种情况包含了所有的n,且满足和为n,最小公倍数正好为⌊n2⌋\lfloor \frac{n}{2} \rfloor⌊2n⌋
其实仔细观察会发现,样例所给的三个数据,正好对应了三个情况
现在考虑k>3的情况,1不会影响最小公倍数的情况,所以我们可以先输出k-3个1,这样不又只剩下3个数的情况了吗?和简单版一样
代码:
#include <bits/stdc++.h>
#include <unordered_map>
#define debug(a, b) printf("%s = %d\n", a, b);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
clock_t startTime, endTime;
//Fe~Jozky
const ll INF_ll= 1e18;
const int INF_int= 0x3f3f3f3f;
void read(){};
template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar)
{x= 0;char c= getchar();bool flag= 0;while (c < '0' || c > '9')flag|= (c == '-'), c= getchar();while (c >= '0' && c <= '9')x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();if (flag)x= -x;read(Ar...);
}
template <typename T> inline void write(T x)
{if (x < 0) {x= ~(x - 1);putchar('-');}if (x > 9)write(x / 10);putchar(x % 10 + '0');
}
void rd_test()
{
#ifdef ONLINE_JUDGE
#elsestartTime= clock();freopen("data.in", "r", stdin);
#endif
}
void Time_test()
{
#ifdef ONLINE_JUDGE
#elseendTime= clock();printf("\nRun Time:%lfs\n", (double)(endTime - startTime) / CLOCKS_PER_SEC);
#endif
}
int main()
{//rd_test();int t;cin >> t;while (t--) {int n, k;cin >> n >> k;for (int i= k; i > 3; i--) {n--;cout << 1 << " ";}if (n & 1) {cout << 1 << " " << n / 2 << " " << n / 2 << endl;}else if ((n / 2) & 1) {cout << 2 << " " << n / 2 - 1 << " " << n / 2 - 1 << endl;}elsecout << n / 2 << " " << n / 4 << " " << n / 4 << endl;}//Time_test();
}