题目
Description
Input
一行两个正整数 n,m。
Output
Sample Input
样例输入1:
1 3
样例输入2:
2 4
样例输入3:
5 5
Sample Output
样例输出1:
108
样例输出2:
629124429
样例输出3:
355944288
Data Constraint
Subtask 1(10pts):n,m ≤ 5。
Subtask 2(20pts):n,m ≤ 50。
Subtask 3(10pts):n,m ≤ 500。
Subtask 4(20pts):n,m ≤ 50000。
Subtask 5(20pts):n,m ≤ 200000。
Subtask 6(20pts):n ≤ 10^8 ,m ≤ 200000。
思路
gcd-lcm容斥
推荐一篇博客:https://www.cnblogs.com/cyf32768/p/12329103.html
代码
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define maxn 200005
#define ll long long
#define mo 998244353
using namespace std;
ll n,m,i,j,k,ans,sum;
int bz[maxn],pri[maxn],tot,phi[maxn];
void getpri(){
phi[1]=1;
for(i=2;i<maxn;i++){
if (!bz[i]) pri[++tot]=i,phi[i]=i-1;
for(j=1;j<=tot&&i*pri[j]<maxn;j++){
bz[i*pri[j]]=1;
if (i%pri[j]==0) {
phi[i*pri[j]]=phi[i]*pri[j];
break;
} else phi[i*pri[j]]=phi[i]*(pri[j]-1);
}
}
}
ll ksm(ll x,ll y,ll p){
ll s=1;
for(;y;y/=2,x=x*x%p) if (y&1)
s=s*x%p;
return s;
}
int main(){
freopen("lg.in","r",stdin);
freopen("lg.out","w",stdout);
scanf("%lld%lld",&n,&m),getpri();
ans=1;
for(ll d=1;d<=m;d++){
ll L=m/d; sum=ksm(L,n,mo-1);
ans=ans*ksm(d,sum*phi[d]%(mo-1)+mo-1,mo)%mo;
for(ll pi=1;pi<=tot&&pri[pi]<=L;pi++){
ll p=pri[pi],cnt=0;
for(ll q=p;q<=L;q=q*p)
cnt+=sum-ksm(L-L/q,n,mo-1);
ans=ans*ksm(p,cnt%(mo-1)*phi[d]%(mo-1)+(mo-1),mo)%mo;
}
}
printf("%lld",ans);
}