ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【JZOJ】6272. 整除 (division)

2019-09-17 21:36:14  阅读:246  来源: 互联网

标签:division 6272 JZOJ int Xij iPi ij PiP Xt


Description

Time Limits: 3000 ms Memory Limits: 262144 KB

Input

Output

Sample Input

0
1
2 3
2 3

Sample Output

6

Data Constraint

思路

考虑题目中的给出素数两两互质这一性质,思考假如N是一个素数时(即c等于1时怎么做)。
很明显此时N<=1e4,则可以从1枚举到N逐个判断。
如果XMX(modN)X^M\equiv X \pmod{N}XM≡X(modN),则Ans++;

考虑c!=1时,假如这里有一个解XtX_tXt​,使得XtMXt(modN)X_t^M\equiv X_t \pmod{N}XtM​≡Xt​(modN),
对于每个质数PiP_iPi​(i=1,2…c),假如有个解XijX_{ij}Xij​使得XijMXij(modPi)X_{ij}^M\equiv X_{ij}\pmod{P_i}XijM​≡Xij​(modPi​)。
那么对于每个t与每个i,必有一个j使得,XtXij(modPi)X_t\equiv X_{ij}\pmod{P_i}Xt​≡Xij​(modPi​)

考虑PiP_iPi​是互质的,那么对于每一组XijX_{ij}Xij​(每个PiP_iPi​贡献一个XijX_{ij}Xij​出来),
都有唯一的一个XtX_tXt​使得
{XtX1j(modP1)XtX2j(modP2)............XtXcj(modPc)\begin{cases} X_t\equiv X_{1j}\pmod{P_1}\\ X_t\equiv X_{2j}\pmod{P_2}\\ ............\\ X_t\equiv X_{cj}\pmod{P_c} \end{cases}⎩⎪⎪⎪⎨⎪⎪⎪⎧​Xt​≡X1j​(modP1​)Xt​≡X2j​(modP2​)............Xt​≡Xcj​(modPc​)​

原因如下:
N=P1P2....PcN=P1*P2....*PcN=P1∗P2....∗Pc,根据中国剩余定理可得,上面的方程组在[1,N]有且只有1个解,
而对于每个个i,XtmodXijX_t \bmod XijXt​modXij的值都是唯一的,即每个XtX_tXt​唯一对应一组XijX_{ij}Xij​。

XtX_tXt​的个数等于XijX_{ij}Xij​的组数,即为每个PiP_iPi​的j值个数相乘。
而对于每个PiP_iPi​的j值个数就可以用c=1的方法去做了。

不过,这题卡常。
对于每个PiP_iPi​值,从1~PiP_iPi​暴枚其合法解数量并判断是一个O(P*log(M))的复杂度。
总计O(TCPlog(M)),最坏情况是2.5e7乘上long long取模的常数,很容易被卡。

考虑对于每个PiP_iPi​,枚举x值时有两种情况:

若x为一个质数,那么直接暴力快速幂算。O(log(M))

若x不为质数,那么把x拆成a*b的形式使得x=abx=a*bx=a∗b(a!=1且b!=1)。
那么xm=ambmx^m=a^m*b^mxm=am∗bm,直接O(1)出解。
(先用线性筛预处理一波,减小常数。)

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXC=55;
const int MAXP=10005;
const int MOD=998244353;
const long long ONE=1;
long long Ans;int f[MAXP];
int ID,K,M,C,P[MAXC],poit[MAXP];
int pcnt,prime[MAXP],visp[MAXP];
int quick_Pow(int x,int y,int p){
	if(y==0)return 1;
	if(y==1)return x;
	if(y%2)return (x*quick_Pow((x*x)%p,y/2,p))%p;
	return quick_Pow((x*x)%p,y/2,p);
}
inline void Init(int L){
	visp[0]=visp[1]=1;
	for(int i=2;i<=L;i++){
		if(!visp[i])prime[++pcnt]=i;
		for(int j=1;j<=pcnt&&prime[j]*i<=L;j++){
			visp[i*prime[j]]=1;
			poit[i*prime[j]]=prime[j];
			if(i%prime[j]==0)break;
		}
	}
}
int main(){
	//freopen("read.in","r",stdin);
	//freopen("output.out","w",stdout);
	freopen("division.in","r",stdin);
	freopen("division.out","w",stdout);
	Init(10000);
	scanf("%d%d",&ID,&K);
	while(K--){
		scanf("%d%d",&C,&M);Ans=1;
		for(int i=1;i<=C;i++)
			scanf("%d",&P[i]);
		sort(P+1,P+C+1);
		for(int i=1;i<=C;i++){
			int ret=2;f[1]=1;
			for(int j=2;j<P[i];j++){
				if(!visp[j])f[j]=quick_Pow(j,M,P[i]);
				else f[j]=(f[poit[j]]*f[j/poit[j]])%P[i];
				if((f[j]-j+P[i])%P[i]==0)ret++;
			}
			Ans=(Ans*ret)%MOD;
		}
		printf("%lld\n",Ans);
	}
}
/*
4
1
2 3
3 37

5
1
3 3
7 11 13
*/

后记

网上还有一种更强的思路,能O(TCLog(t))出解,我就不写了。(原因是我菜爆了写不来
https://www.cnblogs.com/zjlcnblogs/p/11299900.html

标签:division,6272,JZOJ,int,Xij,iPi,ij,PiP,Xt
来源: https://blog.csdn.net/C20191522TL/article/details/99449994

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有