题目
思路
第i名同学速度为,第j名同学速度为,可以解除i与j相隔打一次招呼,总时间为1-n的最小公倍数lcm,所以i与j一共打招呼次,lcm可根据,指数要取整。
第i个同学需要跟(n-i)个同学打招呼,i同学打招呼的次数一共就是,将(n-1)个同学(没有比第n个慢的)再次累加即可得到最后答案的公式(i为2到n),推导如图
AC代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long;
const long long mod = 998244353;
int n;
vector<int> inv(10000007);
vector<bool> vis(10000007,false);
long long Lcm = 1;
//对数
int myLog(int a, int b) {
return floor(log(b) / log(a));
}
//快速幂
int qmi(int a, int b) {
int res = 1;
while (b > 0) {
if (b % 2 == 1) {
res = (1ll)*(res * a) % mod;
}
a = 1ll * a * a % mod;
b >>= 1;
}
return res;
}
//线性逆元
void inverse() {
inv[0] = 1;
inv[1] = 1;
for (int i = 2; i <= n; i++) {
inv[i] = (mod - (mod / i))*inv[mod%i] % mod;
if (!vis[i]) {
Lcm = (1ll) * (Lcm * qmi(i, myLog(i, n))) % mod;
int j = 1;
while (j * i <= n) {
vis[j*i] = true;
j++;
}
}
}
return;
}
int main() {
cin >> n;
long long ans = 0;
inverse();
for (int i = 2; i <= n; i++) {
ans += 1ll * (n - i + 1) * inv[i] % mod;
}
ans %= mod;
ans = 1ll * ans * Lcm % mod;
cout << ans;
return 0;
}