萌 新 求 助 杜教筛 TLE #2 #10
查看原帖
萌 新 求 助 杜教筛 TLE #2 #10
91956
Dreamweaver楼主2021/5/27 20:41
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f
#define re register
#define maxn 1000000
#define int long long
int pri[1000010],phi[1000010],f[1000010];
int cnt=0;
int inv6,inv4;
bool vis[1000010];
int n,mod;
map <int,int> m; 
void Phi(int n)
{
	phi[1]=1;
	vis[1]=true;
	for(re int i=2;i<=n;i++)
	{
		if(!vis[i])
			pri[++cnt]=i,phi[i]=i-1;
		for(re int j=1;j<=cnt&&i*pri[j]<=n;j++)
		{
			vis[i*pri[j]]=true;
			if(i%pri[j]==0)
			{
				phi[i*pri[j]]=phi[i]*pri[j];
				break;
			}
			phi[i*pri[j]]=phi[i]*(pri[j]-1);
		}
	}
	for(re int i=1;i<=n;i++)	f[i]=i*i%mod*phi[i]%mod;
	for(re int i=1;i<=n;i++)	f[i]=(f[i]+f[i-1])%mod;
}
inline int sum_g(int n)
{
	n%=mod;
	return n*(n+1)%mod*(2*n+1)%mod*inv6%mod;
//	return (n*(n+1)/2%mod)*(n*(n+1)/2%mod)%mod;
}
inline int sum_f_g(int n)
{
	n%=mod;
	return n*n%mod*(n+1)%mod*(n+1)%mod*inv4%mod;
}
inline int getans(int n)
{
	if(n<1000000)	return f[n];
	if(m[n])	return m[n];
	int ans=sum_f_g(n);
	for(re int i=2;i<=n;)
	{
		int x=n/i;
		int j=n/x;
		int ans1=(sum_g(j)-sum_g(i-1)+mod)%mod;
		ans1=ans1*getans(x)%mod;
		ans=(ans-ans1+mod)%mod;
		i=j+1;
	}
	return m[n]=ans;
}
int qpow(int a,int b)
{
	int ans=1;
	while(b)
	{
		if(b&1)	ans=ans*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return ans%mod;
}
inline int read(){
    int x=0,f=1;char ch=getchar();
    while (ch<'0'||ch>'9') {if(ch=='-')f=-1; ch=getchar();}
    while (ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0'; ch=getchar();}
    return x*f;
}
int tot;
signed main()
{
//	freopen("a.in","r",stdin);
//	freopen("a.out","w",stdout);
//	printf("%dM\n",(sizeof(dp) >> 20));
	cin>>mod>>n;
	inv6=qpow(6,mod-2);
	inv4=qpow(4,mod-2);
	Phi(1000000);
	for(re int i=1;i<=n;)
	{
		int x=n/i;
		int j=n/x;
		tot=tot+(getans(j)-getans(i-1)+mod)%mod*sum_f_g(x)%mod;
		tot%=mod;
		i=j+1;
	}
	cout<<tot;
	return 0;
}

2021/5/27 20:41
加载中...