2020.03.14日常总结

扶醉桌前 提交于 2020-03-16 20:17:17

洛谷P1593      因子和\color{green}{\text{洛谷P1593\ \ \ \ \ 因子和}}

\color{blue}{【题意】:} 给定 a,ba,b,求 aba^b 的所有因子的和对 99019901 取模的值,即求:

i=1abi(iab)mod  9901\sum\limits_{i=1}^{a^b} i(i|a^b)\mod 9901

1a,b5×1071 \leq a,b \leq 5 \times 10^7

\color{blue}{【思路】:}a=i=1mpikia= \prod\limits_{i=1}^{m} p_i^{k_i},其中 pip_i 是质数,ki0(1im)k_i\geq 0(1 \leq i \leq m)

那么,ab=i=1mpiki×ba^b=\prod\limits_{i=1}^{m} p_i^{k_i \times b}。由定理,答案 ans=i=1m(j=0ki×bpij)\text{ans}=\prod\limits_{i=1}^{m} (\sum\limits_{j=0}^{k_i \times b}p_i^j)

直接算铁定不行,但是由费马小定理得,at11(modt) (ta^{t-1} \equiv 1 \pmod t\ (t是质数)) 。由题意,p=9901p=9901,于是我们可以算出 res=j=0p2pij\text{res=}\sum\limits_{j=0}^{p-2} p_i^j。然后,因为后面的项一定与前面的某一项相等,于是我们可以令这个数列 t2t-2 位为一个循环,于是我们可以直接由 res\text{res} 得到所有循环的总和。对于后面剩余的项,我们可以暴力得到。

举个例子,比如 ki×b=2×tk_i \times b = 2 \times t,我们可以求出 res=j=0p2pij\text{res=}\sum\limits_{j=0}^{p-2} p_i^j,然后答案 ans = res×2+j=03pij\text{ans = res} \times 2 + \sum\limits_{\text{j=0}}^{3} \text{p}_{\text{i}}^j

时间复杂度没用等比数列优,但是需要的知识点少,比较好理解(至少个人认为如此)。

\color{blue}{【代码】:}

const int mod=9901;
int calc(int x,long long t){
	int ret=1,ans=0;
	if (x==mod) return 1;
	else if (t<mod){
		for(int i=0;i<=t;i++){
			ans=(ans+ret)%mod;
			ret=(1ll*ret*x)%mod;
		}
	}
	else{
		for(int i=0;i<=mod-2;i++){
			ans=(ans+ret)%mod;
			ret=(1ll*ret*x)%mod;
		}
		ans=(1ll*ans*((t+1)/(mod-1)))%mod;
		for(int i=1;i<=(t+1)%(mod-1);i++){
			ans=(ans+ret)%mod;
			ret=(1ll*ret*x)%mod;
		}
	}
	return ans;
}
int ans=1,a,b,n;
int main(){
	scanf("%d%d",&a,&b);n=a;
	for(int i=2;1ll*i*i<=n;i++)
		if (n%i==0){
			register int ret=0;
			while (n%i==0){
				n/=i;ret++;
			}
			ans=(1ll*ans*calc(i,1ll*ret*b))%mod;
		}
	if (n>1) ans=(1ll*ans*calc(n,b))%mod;
	printf("%d",(ans+mod)%mod);
	return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!