2018沈阳网络赛C(莫比乌斯函数+容斥)

题目链接:https://nanti.jisuanke.com/t/31444

涉及到平方因子就要想到莫比乌斯辣。。然后用μ的平方来判定有无平方因子,可以得到

\sum_{num=1}^{n}\sum_{i=1}^{num}gay(i)\\= \sum_{num=1}^{n}\sum_{i=1}^{num}\mu^2(i)i^2\\= \sum_{i=1}^{n}\mu^2(i)i^2(n-i+1)\\= (n+1)\sum_{i=1}^{n}\mu^2(i)i^2-\sum_{i=1}^{n}\mu^2(i)i^3

然后就是对这2个求和就可以了,想用杜教筛?上次南京网络赛告诉我们是不行的。。而是要用容斥,枚举素数平方因子,然后做一个容斥,而莫比乌斯函数刚好是他的容斥系数,所以可以得到

\sum_{i=1}^{n}\mu^2(i)i^2\\= \sum_{i=1}^{\sqrt n}\mu(i)\sum_{k=1}^{\left \lfloor \frac{n}{i} \right \rfloor}(ki^2)^2\\= \sum_{i=1}^{\sqrt n}\mu(i)i^4\sum_{k=1}^{\left \lfloor \frac{n}{i} \right \rfloor}k^2

右边的合式类似,所以最终要求

(n+1)\sum_{i=1}^{\sqrt n}\mu(i)i^4\sum_{k=1}^{\left \lfloor \frac{n}{i^2} \right \rfloor}k^2-\sum_{i=1}^{\sqrt n}\mu(i)i^6\sum_{k=1}^{\left \lfloor \frac{n}{i^2} \right \rfloor}k^3

然后sqrt(n)直接求的完了。。

然后还会爆longlong,需要开int128。。。不造为什么跑得贼慢。。明明复杂度那么低。。。

 

 

/**
 *        ┏┓    ┏┓
 *        ┏┛┗━━━━━━━┛┗━━━┓
 *        ┃       ┃  
 *        ┃   ━    ┃
 *        ┃ >   < ┃
 *        ┃       ┃
 *        ┃... ⌒ ...  ┃
 *        ┃       ┃
 *        ┗━┓   ┏━┛
 *          ┃   ┃ Code is far away from bug with the animal protecting          
 *          ┃   ┃   神兽保佑,代码无bug
 *          ┃   ┃           
 *          ┃   ┃        
 *          ┃   ┃
 *          ┃   ┃           
 *          ┃   ┗━━━┓
 *          ┃       ┣┓
 *          ┃       ┏┛
 *          ┗┓┓┏━┳┓┏┛
 *           ┃┫┫ ┃┫┫
 *           ┗┻┛ ┗┻┛
 */ 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge *j=h[x];j;j=j->next)
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
#define eps 1e-12
#define succ(x) (1<>1)
#define NM 100005
#define nm 40005
#define pi 3.1415926535897931
using namespace std;
ll read(){
    ll x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}
 
 
 
 







int tot,prime[NM],mu[NM],m;
__int128 f[NM],g[NM],ans,inf;
ll n;
bool v[NM];



void init(){
    mem(v);tot=0;mem(mu);
    m=1e5;mu[1]=1;
    inc(i,2,m){
	if(!v[i])prime[++tot]=i,mu[i]=-1;
	inc(j,1,tot){
	    if(i*prime[j]>m)break;
	    v[i*prime[j]]++;
	    if(i%prime[j]==0)break;
	    mu[i*prime[j]]=-mu[i];
	}
    }
}


ll sum(ll n){
    __int128 x=n,y=n+1,z=2*n+1;
    if(x%2==0)x/=2;else if(y%2==0)y/=2;else z/=2;
    if(x%3==0)x/=3;else if(y%3==0)y/=3;else z/=3;
    return (ll)(x*y%inf*z%inf);
}
ll pre(ll n){
    __int128 x=n,y=n+1;
    if(x%2==0)x/=2;else y/=2;
    x=x*y%inf;x=x*x%inf;return x;
}

int main(){
    ll _x;init();
    while(~scanf("%lld%lld",&n,&_x)){
	inf=_x;
	inc(i,1,m)f[i]=1LL*mu[i]*i*i*i%inf*i%inf*i%inf*i%inf,g[i]=1LL*mu[i]*i*i*i%inf*i%inf;
	ans=0;
	for(ll i=1;i*i<=n;i++)ans+=inf+g[i]*sum(n/sqr(i))%inf*(n+1)%inf-f[i]*pre(n/sqr(i))%inf,ans%=inf;
	printf("%lld\n",(ll)ans);
    }
    return 0;
}

 

你可能感兴趣的:(数论)