icpc預賽徐州: Easy Math (有關莫比烏斯函式的數學難題)
阿新 • • 發佈:2018-12-09
題意:
求
解析:
如果n有個因子是某個素數的平方,那麼根據莫比烏斯函式,答案為0,所以我們考慮其他的情況
設d為n的一個素因子,那麼n/d與d互質,而莫比烏斯函式又是積性函式,所以有:
而質數的函式值為-1,所以原式變成:
但是我們好像漏了一個東西,d和n/d互質,但是隻有當d和i也互質的時候才能拆出來,而不能拆出來的部分有哪些呢?d為質數,所以i為d的倍數的時候才不互質,所以答案為:
顯然右邊部分為0,答案為:
為什麼後半部分可以把1/d提到前面去呢?因為後半部分的i本來就只能取d的倍數,而前半部分i範圍為1到m,換成1到m/d後就少了很多
接下來令原答案為Ans(n,m),則有:
遞迴到最後Ans(n,0)顯然是0,而Ans(1,m),在n=1時已經取不到d了就不能往下分了,也就是說需要計算以下公式:
這個其實裸杜教篩就可以了。程式碼:
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N=10000111;
#define pill pair<LL ,LL>
int u[N];
LL pre[N];
LL pri[N>>1],now;
bool vis[N];
void init(){
u[1]=1;now=0;
for(LL i=2;i<N-9;i++){
if(!vis[i]){
pri[++now]=i;u[i]=-1;
}
for(int j=1;j<=now&&i*pri[j]<N-9;j++){
vis[i*pri[j]]=1;
u[i*pri[j]]=-u[i];
if(i%pri[j]==0){
u[i*pri[j]]=0;
break;
}
}
}
pre[0]=0;
for(int i=1;i<N-9;i++)pre[i]=u[i]+pre[i-1];
}
unordered_map<LL,LL>M;
LL calculate(LL n){//杜教篩
if(M.find(n)!=M.end())return M[n];
if(n<N-9)return pre[n];
LL ans=1;
for(LL l=2,r;l<=n;l=r+1){
r=n/(n/l);
ans-=(r-l+1ll)*calculate(n/l);
}
return M[n]=ans;
}
bool judge(LL n){//判斷u(n)是否直接=0
for(int i=1;pri[i]*pri[i]<=n;i++){
if(n%pri[i])continue;
n/=pri[i];
if(n%pri[i]==0)return false;
}
return true;
}
LL Ans(LL n,LL m){
if(n==1)return calculate(m);
if(m==0)return 0;
if(!judge(n))return 0;
LL d=-1; //之前定義為int RE了一上午,氣死了
for(int i=1;pri[i]*pri[i]<=n;i++)
if(n%pri[i]==0){d=pri[i];break;}
if(d==-1)d=n;
return Ans(n,m/d)-Ans(n/d,m);
}
int main(){
init();
LL m,n;
cin>>m>>n;
if(!judge(n))return 0*printf("0\n");
return 0*printf("%lld\n",Ans(n,m));
}