题目链接(https://atcoder.jp/contests/abc162/tasks/abc162_e)
Time Limit: 2 sec / Memory Limit: 1024 MB
Score : \(500\) points
Problem Statement
Consider sequences\(\{A_1,...,A_N\}\) of length \(N\) consisting of integers between \(1\) and \(K\) (inclusive).
There are \(K^N\) such sequences. Find the sum of \(\gcd(A_1, ..., A_N)\) over all of them.
Since this sum can be enormous, print the value modulo\((10^9+7)\).Here \(\gcd(A_1, ..., A_N)\)denotes the greatest common divisor of \(A_1, ..., A_N\).
Constraints
\(2 \leq N \leq 10^5\)
\(1\leq K \leq 10^5\)
All values in input are integers.
Input
Input is given from Standard Input in the following format:
N K
Output
Print the sum of \(\gcd(A_1, ..., A_N)\)over all \(K^N\) sequences, modulo \((10^9+7)\).
Sample Input 1
3 2
Sample Output 1
9
\(\gcd(1,1,1)+\gcd(1,1,2)+\gcd(1,2,1)+\gcd(1,2,2)+\gcd(2,1,1)+\gcd(2,1,2)+\gcd(2,2,1)+\gcd(2,2,2)=1+1+1+1+1+1+1+2=9\)
Thus, the answer is 9.
Sample Input 2
3 200
Sample Output 2
10813692
Sample Input 3
100000 100000
Sample Output 3
742202979
Be sure to print the sum modulo\((10^9+7)\).
题意
给一个长度为\(N\)的序列,每一位的值都取\(1\)到\(k\)之间,求所有序列,(单序列)所有数位最大公因数之和,模\(1e9+7\)
思路
(苦脸)初学,很难搞懂,照葫芦画瓢,emo老师讲课笔记++;
第一反应应该枚举最大公因数\(d\),则\(1≤d≤k\),接下来再看有多少组 \(\gcd(A_1, ..., A_N) == 1\)
所以初步可以写出
\(ans = \sum_{d=1}^kd\sum_{1≤A_i≤k}[gcd(A_1,...,A_N) = d]\)
设\(f(d) = \sum_{1≤A_i≤k}[gcd(A_1,...,A_N) = d]\)
\(g(d) = \sum_{d|d'}f(d') = \sum_{1≤A_i≤k}[d|A_1][d|A_2]...[d|A_k]\)
\(d\)如果是\(A_i\)的倍数的话,他就有\(\lfloor n/d \rfloor\)种取法
那么求和可得\(g(d) = \sum_{1≤A_i≤k}\lfloor n/d \rfloor^N\)
就可以知道\(f(d) = \sum_{d|d'}μ(d'/d)g(d') = \sum_{d|d'}μ(d'/d)\lfloor k/d' \rfloor^N\)
代回原来的式子可得
\(ans = \sum_{d=1}^kd\sum_{d|d'}μ(d'/d)\lfloor k/d' \rfloor^N\)
置换两个求和号
\(ans = \sum_{d'=1}^k\lfloor k/d' \rfloor^N\sum_{d|d'}dμ(d'/d)\)
又因为\(\sum_{d|d'}dμ(d'/d) =φ(d')\)(相当于是用充斥的方法去计算\(φ(d')\)的数量)
证明:(暂时咕,马上补)
所以\(ans = \sum_{d' = 1} ^ k\lfloor k/d' \rfloor^Nφ(d')\)
复杂度\(O(klogN)\)
AC代码
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define int long long
#define ull unsigned long long
#define PII pair<int,int>
#define endl '\n'
using namespace std;
typedef long long ll;
const int N = 1e5 + 100;
const int mod = 1e9 + 7;
const double pi = acos(-1.0);
int t, n, k;
int a[N],b[N];
int gcd(int a, int b) {return b ? gcd(b, a % b) : a;}
int quickpow(int a, int b) {//快速幂
int res = 1;
while (b > 0) {
if (b & 1) res = res * a % mod;
b >>= 1;
a = a * a % mod;
}
return res;
}
void init() {//初始化
for (int i = 0; i <= n; i++) {
a[i] = 0;
b[i] = 0;
}
return;
}
void solve() {
init();
int ans = 0;
for (int i = 1; i <= k; i++) {//求┕k/d'┙^N
a[i] = quickpow(k / i, n) % mod;
}
for (int i = k; i >= 1; i--) {//求φ(d')
b[i] = a[i];
for (int j = i << 1; j <= k; j += i) {
b[i] -= b[j];
}
b[i] = (b[i] + mod) % mod;
}
for (int i = 1; i <= k;i ++) {//相乘累加
ans += (b[i] * i) % mod;
}
cout << (ans + mod) % mod << endl;//取模输出
return;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
while (cin >> n >> k) {
solve();
}
return 0;
}