Extracurricular Sports(PKU Campus 2016 D)
题目大意
点此看题目
找n个不同的数
a
1
,
a
2
,
…
…
,
a
n
a_1,a_2,……,a_n
a1,a2,……,an,使得
l
c
m
(
∑
i
=
1
n
a
i
)
=
∑
i
=
1
n
a
i
lcm(\sum_{i=1}^{n}a_i)=\sum_{i=1}^{n}a_i
lcm(∑i=1nai)=∑i=1nai,输出
a
i
a_i
ai
思路
乍一看,肯定是没有什么思路的,但是我们仔细想一下,我们对于每个n,我们假设
n
−
2
n-2
n−2存在解这不是废话么?肯定存在啊,我们设
s
u
m
=
∑
i
=
1
n
−
2
a
[
n
−
2
]
[
i
]
sum=\sum_{i=1}^{n-2}a[n-2][i]
sum=∑i=1n−2a[n−2][i],其中
a
[
n
−
2
]
a[n-2]
a[n−2]表示
n
=
n
−
2
n=n-2
n=n−2时的
a
a
a数组,那么,当
a
[
n
]
[
n
−
1
]
=
s
u
m
×
2
,
a
[
n
]
[
n
]
=
s
u
m
×
3
a[n][n-1]=sum\times 2,a[n][n]=sum \times 3
a[n][n−1]=sum×2,a[n][n]=sum×3,这个
a
a
a数组显然满足题意这个还用我说么?
l
c
m
(
1
,
2
,
3
)
=
1
+
2
+
3
=
6
lcm(1,2,3)=1+2+3=6
lcm(1,2,3)=1+2+3=6啊!,所以我们就可以
O
(
n
2
)
O(n^2)
O(n2)(其中一个n是用来枚举,另一个是用来把前面赋值到现在的)解决这道题,但是有一个条件使得这道题码量巨大,就是
a
i
<
=
1
0
100
a_i<=10^{100}
ai<=10100,所以我们就必须用高精度了,耗了我好久好久啊,再注意一下,当
n
=
2
n=2
n=2时我们需要直接输出
−
1
-1
−1我就是这么错了一次的,以后要认真读题了啊
代码
#include <set>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define Int register int
#define MAXN 205
int n;
struct BigNum
{
string num;
BigNum(){}
BigNum (string _num){num = _num;}
BigNum operator * (const BigNum &p)const
{
int a1[MAXN] = {},a2[MAXN] = {},a3[MAXN] = {};
int len1 = num.length(),len2 = p.num.length(),len3 = 0;
for (Int i = len1 - 1;i >= 0;-- i) a1[len1 - i] = num[i] - '0';
for (Int i = len2 - 1;i >= 0;-- i) a2[len2 - i] = p.num[i] - '0';
for (Int i = 1;i <= len1;++ i)
for (Int j = 1;j <= len2;++ j)
{
int where = i + j - 1;
a3[where] += a1[i] * a2[j];
if (a3[where] >= 10)
{
a3[where + 1] += a3[where] / 10;
a3[where] %= 10;
}
if (a3[where]) len3 = max(len3,where);
if (a3[where + 1]) len3 = max(len3,where + 1);
}
for (Int i = 1;i <= len3;++ i)
if (a3[i] >= 10)
{
a3[i + 1] += a3[i] / 10;
a3[i] %= 10;
len3 = max(len3,i + 1);
}
string ans;
for (Int i = len3;i >= 1;-- i)
ans += a3[i] + '0';
return BigNum (ans);
}
BigNum operator + (const BigNum &p)const
{
int a1[MAXN] = {},a2[MAXN] = {},a3[MAXN] = {};
int len1 = num.length(),len2 = p.num.length(),len3 = 0;
for (Int i = 0;i < len1;++ i) a1[len1 - i] = num[i] - '0';
for (Int i = 0;i < len2;++ i) a2[len2 - i] = p.num[i] - '0';
if (len1 < len2)
{
swap (len1,len2);
swap (a1,a2);
}
for (Int i = 1;i <= len1;++ i)
{
len3 = max(len3,i);
a3[i] += a1[i] + a2[i];
if (a3[i] >= 10)
{
a3[i + 1] += a3[i] / 10;
a3[i] %= 10;
len3 = max(len3,i + 1);
}
}
for (Int i = 1;i <= len3;++ i)
if (a3[i] >= 10)
{
a3[i + 1] += a3[i] / 10;
a3[i] %= 10;
len3 = max(len3,i + 1);
}
string ans;
for (Int i = len3;i >= 1;-- i)
ans += a3[i] + '0';
return BigNum (ans);
}
};
BigNum sum[MAXN],a[MAXN][MAXN];
void read (int &x)
{
x = 0;char c = getchar();int f = 1;
while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}
while (c >= '0' && c <= '9'){x = (x << 3) + (x << 1) + c - '0';c = getchar();}
x *= f;return ;
}
void write (int x)
{
if (x < 0){x = -x;putchar ('-');}
if (x > 9) write (x / 10);
putchar (x % 10 + '0');
}
signed main()
{
int times;
read (times);
while (times --)
{
read (n);
if (n == 2)
{
puts ("-1");
continue;
}
sum[3] = BigNum("6"),sum[4] = BigNum("18");
a[3][1] = BigNum("1"),a[3][2] = BigNum("2"),a[3][3] = BigNum("3");
a[4][1] = BigNum("1"),a[4][2] = BigNum("2"),a[4][3] = BigNum("6"),a[4][4] = BigNum("9");
for (Int i = 5;i <= n;++ i)
{
for (Int j = 1;j <= i - 2;++ j)
a[i][j] = a[i - 2][j];
a[i][i - 1] = sum[i - 2] * BigNum("2");
a[i][i] = sum[i - 2] * BigNum("3");
sum[i] = sum[i - 2] + a[i][i - 1] + a[i][i];
}
for (Int i = 1;i <= n;++ i)
cout << a[n][i].num << endl;
}
return 0;
}