ACM-ICPC 2018 徐州赛区网络预赛 D 杜教筛 前缀和
链接 https://nanti.jisuanke.com/t/31456
参考题解 https://blog.csdn.net/ftx456789/article/details/82590044
1 #include <bits/stdc++.h> 2 #define pb push_back 3 #define mp make_pair 4 #define fi first 5 #define se second 6 #define all(a) (a).begin(), (a).end() 7 #define fillchar(a, x) memset(a, x, sizeof(a)) 8 #define huan printf("\n"); 9 #define debug(a,b) cout<<a<<" "<<b<<" "<<endl; 10 using namespace std; 11 const int maxn=1e6+10; 12 typedef long long ll; 13 map<ll,ll> ma,yin; 14 int check[maxn],prime[maxn],mu[maxn]; 15 void Mobius(int N)//莫比乌斯函数线性筛 16 { 17 int pos=0;mu[1]=1; 18 for (int i = 2 ; i <= N ; i++) 19 { 20 if (!check[i]) 21 prime[pos++] = i,mu[i]=-1; 22 for (int j = 0 ; j < pos && i*prime[j] <= N ; j++) 23 { 24 check[i*prime[j]] = 1; 25 if (i % prime[j] == 0) 26 { 27 mu[i*prime[j]]=0; 28 break; 29 } 30 mu[i*prime[j]]=-mu[i]; 31 } 32 } 33 for(int i=2;i<=N;i++) 34 mu[i]+=mu[i-1]; 35 } 36 ll sum(ll a) 37 { 38 if(a<=1e6) 39 return mu[a]; 40 if(ma.count(a)) 41 return ma[a]; 42 ll temp=1; 43 for(ll i=2;i<=a;) 44 { 45 ll t=a/i; 46 ll k=a/t; 47 temp-=(k-i+1)*sum(t); 48 i=k+1; 49 } 50 return ma[a]=temp; 51 } 52 void shai(ll n)//筛素因子 53 { 54 ll x=n; 55 for(ll i=2;i*i<=x;i++) 56 { 57 while(x%i==0) 58 { 59 yin[i]++; 60 x/=i; 61 } 62 } 63 if(x>1)yin[x]++; 64 } 65 ll solve(ll n,ll m) 66 { 67 if(m==0)return 0;//m等于0就是0喽 68 if(n==1)return sum(m);//n等于1 就是莫比乌斯函数 u 的前 m 项和 69 for(auto it:yin) 70 { 71 if(n%it.fi==0) 72 { 73 return solve(n,m/it.fi)-solve(n/it.fi,m); 74 } 75 } 76 } 77 int main() 78 { 79 Mobius(1e6); 80 ll n,m; 81 cin>>n>>m; 82 shai(m); 83 for(auto it:yin) 84 if(it.se>1) 85 { 86 cout<<0<<endl; 87 return 0; 88 } 89 cout<<solve(m,n)<<endl; 90 return 0; 91 }