萌新刚学莫比乌斯反演,卡到65分不会做了,求助
查看原帖
萌新刚学莫比乌斯反演,卡到65分不会做了,求助
135258
charm1楼主2021/3/11 07:21

RT

#include <bits/stdc++.h>
#define int unsigned long long
using namespace std;
const int maxn=1000005;
int n;
int sum[maxn],mu[maxn];
bool p[maxn];
inline int read(){
	int ret=0,f=1;	char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
	while(isdigit(ch)){ret=ret*10+ch-'0';ch=getchar();}
	return ret*f;
}
void prework(){
	int k,j,i;
	sum[1]=1;
	for(k=1;k<maxn;k++)	mu[k]=1;
	for(k=2;k<maxn;k++){
		if(!p[k]){
			for(j=k;j<maxn;j+=k){
				p[j]=1;
				if(j%(k*k))	mu[j]=-mu[j];
				else		mu[j]=0;
			}
		}
		sum[k]=sum[k-1]+mu[k];
	}
}
int sum1(int x){return x>0?(x*(x+1))>>1:0;}
int sum2(int ll,int rr,int l,int r){
	int ans=(rr-ll+1)*(r-l+1);
	ans-=sum1(min(rr-r+1,r-l+1))-sum1(min(ll-r,r-l+1));
	return ans;
}
int calc(int d){
	int ans=0,m=n/d,c=m/d;
    for(int l=1,r;l<=c;l=r+1){
		r=c/(c/l);  int x=c/l;
	    for(int ll=l+1,rr;ll<=(r<<1)-1&&ll<=x;ll=rr+1){
			rr=min(x/(x/ll),(r<<1)-1);
	    	ans+=(x/ll)*sum2(ll,rr,l,r);
		}
	}
	return ans;
}
int Getsum(int n){
	if(n<maxn)  return sum[n];
	int ans=1;
	for(int l=2,r;l<=n;l=r+1){
		r=n/(n/l);
		ans-=(r-l+1)*Getsum(n/l);
	}
	return ans;
}
void solve(){
	int ans=0;
	for(int l=1,r;l<=n;l=r+1){
		r=n/(n/l);
		ans+=(Getsum(r)-Getsum(l-1))*calc(l);
	}
	printf("%lld\n",ans);
}
signed main(){
	n=read();
	prework();	solve();
	return 0;
}
2021/3/11 07:21
加载中...