数论课堂
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
",ans);
return 0;
}