JZOJ6272.【NOIP2019提高组A】整除

Description

传送门
JZOJ6272.【NOIP2019提高组A】整除_第1张图片
JZOJ6272.【NOIP2019提高组A】整除_第2张图片
在这里插入图片描述

Solution

  • n|xm-x等价于:任意p,满足 p|xm-x。p为质因子。
  • 将n的质因子p分开考虑。
  • 不难得出,在模p意义下满足以上条件的解y(y
  • 那么我们要求最终解x同时满足所有质因子条件,每一个质因子都可以选择一些解y中的一个并且要求x与y在模p意义下同余,那么这个条件肯定满足了。如果cnti表示对于第i个质因子y的个数,那么共有cnt1* cnt2 * cnt3…*cntc种方案。
  • 这样我们就可以得到其中一种方案的c条同余方程。
  • 根据中国剩余定理,我们可以知道,在模M(M=所有模数即质因子的乘积,在这里就是n)下,这些同余方程有且只有一个解。
  • 所以说一种同余方程的方案就对应着一个解。所以实际上解的个数就等于方案数cnt1* cnt2 * cnt3…*cntc。
  • 求质因子内满足条件的个数等同于求所有xm%p (x
  • 素数就直接快速幂。但是会被卡常,所以我们让m%(p-1),因为xp-1=1(mod p)

update 还有一种更秀的做法,碾爆正解

source%%%

JZOJ6272.【NOIP2019提高组A】整除_第3张图片

我的辣鸡代码

#include
#include
#include
#include
#define ll long long 
#define mo 998244353
#define maxp 10005
using namespace std;

int id,T,c,m,mm,i,j,k,p;
int tot,pri[maxp],bz[maxp],f[maxp];
ll ans,cnt;

int ksm(int x,int y){
	ll s=1;
	for(;y;y/=2,x=x*x%p) if (y&1)
		s=s*x%p;
	return s;
}

int main(){
	for(i=2;i

数论大佬的做法

#include
#include
#include
#include
#define ll long long 
#define mo 998244353
#define maxp 10005
using namespace std;

int id,T,c,m,mm,i,j,k,p;
ll ans,cnt;

int gcd(int x,int y){
	return (x%y==0)?y:gcd(y,x%y);
}

int main(){
	scanf("%d",&id);
	scanf("%d",&T);
	while (T--){
		scanf("%d%d",&c,&m);
		ans=1;
		while (c--){
			scanf("%d",&p);
			ans=1ll*ans*(gcd(m-1,p-1)+1)%mo;
		}
		printf("%lld\n",ans);
	}	
}

你可能感兴趣的:(题解,数论,计数,中国剩余定理)