【JZOJ 省选模拟】 lg

题目

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);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值