CF1712B
题意
构造一个 \(n\) 的排列 \(p\),使得 $ \sum\limits_{i=1}^n \operatorname{lcm}(i,p_i)$ 最大。
分析
首先要知道,\(\operatorname{lcm}\) 是求两数的最小公倍数。因此,我们把思考方向引向公约数与公倍数。先回顾一下这条等式,对于任意的正整数 \(m\) 和 \(n\) 都有
\[\gcd(m,n) \times \operatorname{lcm}(m,n)=m \times n
\]
移项得
\[\operatorname{lcm}(m,n)= \dfrac {m \times n}{\gcd(m,n)}
\]
既然要使等式的左边尽可能大,那么右边的分母自然越小越好(最小为 \(1\))。存在一种情况,使得 \(\gcd(m,n)=1\),即我们常说的互质。回顾一下互质的定义:若 \(m\) 和 \(n\) 为两个相邻的正整数,则有 \(\gcd(m,n)=1\)。因此我们就要使题目中的 \(i\) 和 \(p_i\) 互质,使得分母变为 \(1\)(最小的数)。
那么这题做法就很显然了:设 \(i\) 为奇数,则 \(i+1\) 为偶数,令 \(p_i=i+1\),\(p_{i+1}=i\),则 \(\gcd(i,p_i)=1\),\(\gcd(i+1,p_{i+1})=1\),满足条件。特别地,当 \(n\) 为奇数时,我们直接令 \(p_1=1\),其余情况从 \(2\) 开始,也满足条件,避免了剩下一个数的情况。
代码见下:
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
if(n&1)
{
cout<<1<<' ';
for(int i=2;i<=n;i++)
if(i&1^1)//等价于 i%2==0
cout<<i+1<<' ';
else
cout<<i-1<<' ';
}
else
{
for(int i=1;i<=n;i++)
if(i&1)
cout<<i+1<<' ';
else
cout<<i-1<<' ';
}
cout<<endl;
}
return 0;
}
还是菜。