题意:
求在1~n中与n互质的数的四次方的和
容斥不会的建议先看一下入门题
解题思路:
先素数打表,求出n的质因子,求出1~n的n个数的四次方的和,容斥原理,减去奇数个质因子相乘的数以及它的倍数的四次方,加上偶数个相乘的数以及它的倍数的四次方
1~n的四次方求和公式:sum = n*(n+1)*(6*n*n*n+9*n*n+n-1)/30
注意:2^4+4^4+6^4+8^4+10^4 = 2^4*(1+2^4+3^4+4^4+5^4) 这是奇(偶)数个质因子相乘的数以及它的倍数的四次方的小优化
最后就是除以30这里,需要求逆元,可以直接套用(a/b)%nod = a*b^(mod-2)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
#define LL long long
#define mod 1000000007
#define inf 1000000
int a[inf],b[inf],pri[10004],vis[10004];
int len,k,li;
LL J;
void prime()
{
li=0;
memset(vis,0,sizeof(vis));
for(int i=2;i<10004;i++)
{
if(vis[i]==0)
{
pri[li++]=i;
for(int j=i;j<10004;j+=i)
{
vis[j]=1;
}
}
}
}
void init1(LL x)
{
for(int i=0;i<li;i++)
{
if(pri[i]*pri[i]>x) break;
if(x%pri[i]==0)
{
while(x%pri[i]==0)
{
x/=pri[i];
}
b[len++] = pri[i];
}
if(x==1) break;
}
if(x!=1) b[len++]=x;
}
int add(LL N)
{
LL a=N%mod ;
LL b=(N+1)%mod ;
LL c=6*N%mod ;
LL d=c*N%mod ;
LL e=d*N%mod ;
LL f=9*N%mod ;
LL g=f*N%mod ;
LL h=(e+g+N-1)%mod ;
LL i=a*b%mod ;
i=i*h%mod ;
i=i*J%mod ;
return (i+mod)%mod ;
}
LL pow(LL x ,LL y)
{
LL ans=1 ;
for(;y;y>>=1)
{
if(y&1)
{
ans*=x ;
if(ans>=mod)
ans%=mod ;
}
x*=x ;
if(x>=mod)
x%=mod ;
}
return (ans+mod)%mod ;
}
int init2(LL x)
{
k=1;
a[0]=-1;
int s=0;
for(int i=0;i<len;i++)
{
int l=k;
for(int j = 0;j<l;j++)
{
a[k] = -1*a[j]*b[i];
if(a[k]<0)
{
int t=-a[k];
s = (s-(pow(t,4)*add(x/t))%mod)%mod;
}
else
{
int t = a[k];
s = (s+(pow(t,4)*add(x/t))%mod)%mod;
}
k++;
}
}
return s;
}
int main()
{
int t;
scanf("%d",&t);
prime();
J = pow(30,mod-2);
while(t--)
{
LL n;
scanf("%lld",&n);
LL sum = add(n);
len=0;
init1(n);
sum = (sum - init2(n)+mod)%mod;
printf("%lld\n",sum);
}
return 0;
}
本文介绍了一个算法,用于计算1到n中与n互质的数的四次方之和。利用素数表、容斥原理和四次方求和公式,优化计算过程。
819

被折叠的 条评论
为什么被折叠?



