50分求助
查看原帖
50分求助
315398
小杨小小杨楼主2023/4/17 15:52

看到第二篇题解后也想试试,然后逝世了....

求助

#include<bits/stdc++.h>
#define long long int
using namespace std;
const int inf=2e9;
bool plot[300001]; 
int m,n,ans,flag[300001],tmp,i,j,dp[21605][55],c[300001],cnt,t,w,bao,mid,num;
int pd(int x,int y){
	int ans=1;
	while (y){
		if (y&1) if (ans>=inf/x) ans=inf; else ans*=x;
		y>>=1;
		if (x>=inf/x) x=inf; else x*=x;
	}
	return ans;
}
int DupelexV(int x,int y){
	if (x<=21600&&y<=50) return dp[x][y];
	if (!x||!y) return x;
	if (1ll*flag[y]*flag[y]>=x&&x<=21600) return max(0,c[x]-y);
	return DupelexV(x,y-1)-DupelexV(x/flag[y],y-1);
}
signed main(){
	scanf("%lld",&m);
	for(i=2;i<=21600;i++){ 
	    if(!plot[i]) flag[++tmp]=i;
	    for(j=1;j<=tmp&&i*flag[j]<=21600;j++){
	        plot[i*flag[j]]=1;
	        if (!i%flag[j]) break;
		}
	}
	for (i=1;i<=21600;i++) c[i]=(cnt+=1-plot[i]);
	for (i=1;i<=21600;i++) dp[i][0]=i;
	for (i=1;i<=21600;i++)
		for (j=1;j<=50;j++)
			dp[i][j]=dp[i][j-1]-dp[i/flag[j]][j-1];
	if (m<21600) printf("%lld\n",c[m]-1);
	else{
		t=2;w=21600;bao=1;
		while (t<=w){
			mid=(t+w)>>1;
			if (pd(mid,3)<=m) bao=mid,t=mid+1;
			else w=mid-1;
		}
		n=c[bao];ans=DupelexV(m,n)+n-1;
		for (n++;flag[n]*flag[n]<=m;n++) ans-=c[m/flag[n]]-c[flag[n]]+1;
		printf("%lld\n",ans);
	}
	return 0;
}
2023/4/17 15:52
加载中...