Atcoder Beginer Contest 162 E - Sum of gcd of Tuples (Hard)
一.题目大意
有
N
N
N个数,每一个数都在
[
1
,
K
]
[1,K]
[1,K]之间,共有
K
N
K^N
KN种不同的排列,对于每一种排列求
g
c
d
gcd
gcd,把每个
g
c
d
gcd
gcd加起来,模
1
0
9
+
7
10^9+7
109+7。
二.大体思路
不能暴力,否则~~~
考虑对于
x
x
x的情况:
g
c
d
(
A
1
,
A
2
,
.
.
.
,
A
N
)
=
x
gcd(A_1,A_2,...,A_N)=x
gcd(A1,A2,...,AN)=x
满足(
k
i
表
示
x
是
A
i
的
k
i
倍
k_i表示x是A_i的k_i倍
ki表示x是Ai的ki倍):
A
1
=
x
k
1
,
A
2
=
x
k
2
,
.
.
.
,
A
N
=
x
k
N
A_1=xk_1,A_2=xk_2,...,A_N=xk_N
A1=xk1,A2=xk2,...,AN=xkN
每一个
k
i
k_i
ki共有
[
K
/
x
]
[K/x]
[K/x]种取值,一共有
N
N
N个,所以有
[
K
/
x
]
N
[K/x]^N
[K/x]N中排列方式。
不过,这样会挂~~
因为不能全是
x
x
x的倍数的倍数,所以要减掉
x
=
x
的
倍
数
的
倍
数
的
情
况
x=x的倍数的倍数的情况
x=x的倍数的倍数的情况(懵 )
即若
y
y
y是
x
x
x的倍数(不是
x
x
x),则要减掉
y
y
y的情况数(可以用
a
n
s
y
ans_y
ansy存储)
三.上代码!!!
#include "bits/stdc++.h"
using namespace std;
const int maxN=1e5+10;
const long long MOD=1e9+7;
int n;
long long k;
long long ans[maxN];
long long res=0LL;
long long fast_mi(long long a,int p)
{
if(p==0)
{
return 1LL;
}
long long tmp=fast_mi(a,p>>1);
tmp=tmp*tmp%MOD;
if(p&1)
{
tmp=tmp*a%MOD;
}
return tmp;
}
int main()
{
cin>>n>>k;
for(long long x=k;x>=1LL;x--)
{
long long multi_num=k/x;
long long num=fast_mi(multi_num,n);
for(int i=x+x;i<=k;i+=x)
{
num=(num-ans[i]+MOD)%MOD;
}
ans[x]=num;
res=(res+num*x)%MOD;
}
cout<<res<<endl;
return 0;
}
EOF