数论课堂

数论课堂

a[i]直接O(n)递推

然后就是求约数集合d[i]

d[i]暴力求是O(n sqrt(n)) 的过不去

然后这里的优化

for(int i=1;i<=n;i++)
	for(int j=1;j<=n/i;j++)
		d[i*j]=d[i*j]*i%p;

复杂度 n/1+n/2+n/3+...+n/n=n log n

完整代码:

#include<bits/stdc++.h> 
using namespace std;
typedef unsigned long long ll;
int p=10007,n;
ll q,a[300005],ans,d[300005];
ll qpow(ll a,ll b){
	ll ans=1;
	while(b){
		if(b&1)ans=ans*a%p;
		a=a*a%p;
		b>>=1;
	}
	return ans;
}
int main(){
	scanf("%d",&n);
	scanf("%lld%lld%lld%lld",&q,&a[1],&a[2],&a[3]);
	for(int i=4;i<=n;i++)a[i]=(a[i-3]+a[i-2]+a[i-1])%q;
	for(int i=1;i<=n;i++)d[i]=1;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n/i;j++)
			d[i*j]=d[i*j]*i%p;
	for(int i=1;i<=n;i++)ans=(ans+qpow(d[i],a[i]))%p;
	printf("%u\n",ans);
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/liukx/p/12934385.html