https://www.lydsy.com/JudgeOnline/problem.php?id=3944
第一次写杜教筛
被卡常数卡死
感觉还是比较神奇的
我终于理解了杜教筛的本质
哈哈哈
不过被卡常数了
没关系
不过学长的代码5秒钟切了
厉害
不过一向追求代码漂亮美观的我
感觉还是我写的代码比较漂亮
超时就超时吧
而且也不光我超时
感觉这题时限有点变态
随便从别的博客上找了几个别人的代码交上去
全他妈超时
超时代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=4e6;
int prime[N+10],tot;
int v[N+10];
ll phi[N+10];
ll miu[N+10];
map<ll,ll>_phi,_miu;
ll calcmiu(ll n){
if(n<N) return miu[n];
if(_miu.count(n)) return _miu[n];
ll x=2,ans=1;
while(x<=n){
ll y=n/(n/x);
ans-=calcmiu(n/x)*(y-x+1);
x=y+1;
}
return _miu[n]=ans;
}
ll calcphi(ll n){
if(n<N) return phi[n];
if(_phi.count(n)) return _phi[n];
ll x=2,ans=n*(n+1)/2;
while(x<=n){
ll y=n/(n/x);
ans-=calcphi(n/x)*(y-x+1);
x=y+1;
}
return _phi[n]=ans;
}
int main(){
for(int i=1;i<=N;++i) phi[i]=i;
for(int i=2;i<=N;++i){
if(phi[i]==i)
for(int j=i;j<=N;j+=i)
phi[j]=phi[j]/i*(i-1);
}
for(int i=1;i<=N;i++) miu[i]=1,v[i]=0;
for(int i=2;i<=N;i++){
if(v[i]) continue;
miu[i] = -1;
for(int j=2*i;j<=N;j+=i){
v[j]=1;
if((j/i)%i==0) miu[j]=0;
else miu[j]*=-1;
}
}
for(int i=2;i<=N;++i){
phi[i]+=phi[i-1];
miu[i]+=miu[i-1];
}
int T;
scanf("%d",&T);
while(T--){
ll x;
scanf("%lld",&x);
cout<<calcphi(x)<<" "<<calcmiu(x)<<endl;
}
}
学长的AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=4e6;
int prime[N+10],tot;
int v[N+10];
ll phi[N+10];
ll miu[N+10];
map<ll,ll>_phi,_miu;
ll calcmiu(ll n){
if(n<N) return miu[n];
if(_miu.count(n)) return _miu[n];
ll x=2,ans=1;
while(x<=n){
ll y=n/(n/x);
ans-=calcmiu(n/x)*(y-x+1);
x=y+1;
}
return _miu[n]=ans;
}
ll calcphi(ll n){
if(n<N) return phi[n];
if(_phi.count(n)) return _phi[n];
ll x=2,ans=n*(n+1)/2;
while(x<=n){
ll y=n/(n/x);
ans-=calcphi(n/x)*(y-x+1);
x=y+1;
}
return _phi[n]=ans;
}
int main(){
for(int i=1;i<=N;++i) phi[i]=i;
for(int i=2;i<=N;++i){
if(phi[i]==i)
for(int j=i;j<=N;j+=i)
phi[j]=phi[j]/i*(i-1);
}
for(int i=1;i<=N;i++) miu[i]=1,v[i]=0;
for(int i=2;i<=N;i++){
if(v[i]) continue;
miu[i] = -1;
for(int j=2*i;j<=N;j+=i){
v[j]=1;
if((j/i)%i==0) miu[j]=0;
else miu[j]*=-1;
}
}
for(int i=2;i<=N;++i){
phi[i]+=phi[i-1];
miu[i]+=miu[i-1];
}
int T;
scanf("%d",&T);
while(T--){
ll x;
scanf("%lld",&x);
cout<<calcphi(x)<<" "<<calcmiu(x)<<endl;
}
}