Min_25 筛最后三点 RE 求调,悬一关
查看原帖
Min_25 筛最后三点 RE 求调,悬一关
1308728
xsmfollower楼主2025/1/28 10:23

rt,照着题解打的,不知道哪里有问题。

#include<iostream>
using namespace std;
typedef long long ll;
const int N=1e5+10,Mod=1e9+7,Inv=166666668;
ll n,w[N]; int cnt,prime[N],sum1[N],sum2[N],id1[N],id2[N],g1[N],g2[N]; bool isprime[N];
int s(ll x,int y) {
	if(prime[y]>=x) return 0;
	int k=1ll*x*x<=n?id1[x]:id2[n/x],ans=((g2[k]-g1[k]+Mod)%Mod-(sum2[y]-sum1[y]+Mod)%Mod+Mod)%Mod;
	for(int i=y+1;i<=cnt&&1ll*prime[i]*prime[i]<=x;i++) {
		ll p=prime[i];
		for(int j=1;p<=x;j++,p*=prime[i]) ans=(ans+1ll*(p%Mod)*(p%Mod-1)%Mod*(s(x/p,i)+(j!=1))%Mod)%Mod;
	}
	return ans;
}
int main() {
	ios::sync_with_stdio(false),cin.tie(nullptr);
	int m=0; cin>>n;
	for(int i=2;1ll*i*i<=n;i++) isprime[i]=true;
	for(int i=2;1ll*i*i<=n;i++) {
		if(isprime[i]) prime[++cnt]=i;
		for(int j=1;j<=cnt&&1ll*i*prime[j]*i*prime[j]<=n;j++) {
			isprime[i*prime[j]]=false;
			if(!(i%prime[j])) break;
		}
	}
	for(int i=1;i<=cnt;i++) sum1[i]=(sum1[i-1]+prime[i])%Mod,sum2[i]=(sum2[i-1]+1ll*prime[i]*prime[i]%Mod)%Mod;
	for(ll i=1;i<=n;i=n/(n/i)+1) {
		w[++m]=n/i,g1[m]=1ll*w[m]*(w[m]+1)/2%Mod-1,g2[m]=1ll*w[m]*(w[m]+1)%Mod*(2*w[m]+1)%Mod*Inv%Mod-1;
		if(1ll*w[m]*w[m]<=n) id1[w[m]]=m;
		else id2[n/w[m]]=m;
	}
	for(int i=1;i<=cnt;i++)
		for(int j=1;j<=m&&1ll*prime[i]*prime[i]<=w[j];j++) {
			ll k=w[j]/prime[i]; k=k*k<=n?id1[k]:id2[n/k];
			g1[j]=(g1[j]-1ll*prime[i]*(g1[k]-sum1[i-1]+Mod)%Mod+Mod)%Mod;
			g2[j]=(g2[j]-1ll*prime[i]*prime[i]%Mod*(g2[k]-sum2[i-1]+Mod)%Mod+Mod)%Mod;
		}
	cout<<(s(n,0)+1)%Mod;
	return 0;
}
2025/1/28 10:23
加载中...