模拟赛t3 太阳神(ra) 题解
太阳神
求满足如下条件的数对对数:均为正整数且而。
答案对取模 .
原题题解写的看不懂
题意即为求
.
转化为
把最大公约数提出来,化为
之后令
于是我们可以先枚举,算出即可,由于只有个,所以只需要利用数论分块枚举次即可!
接下来考虑如何快速求出
我们发现:
相当于把质因数分解为,对于每个,要么给,要么给,所以有种方案,即的质数约数个数。
于是
是可以线性筛的,于是我们就可以求了!
但是考虑到过于大的数据范围,我们考虑优化:
令
则有
这里面是可以数论分块求得,于是我们可以递归来求了!别忘了加上记忆化,这里可以用来记忆化。
我们在不爆空的情况下尽可能多筛一些,我这里就筛到了.对于每一个,时间复杂度就是.
计算一下总时间复杂度():
于是有
所以时间复杂度为
#define ll long long
#define chr 10000000
const int maxn=1e7+5;
int f[maxn],num[maxn],p[maxn/10],cnt=0;
bool vis[maxn];
ll N;
const int mod=1e9+7;
void gt(int n){
for(int i=2;i<=n;i++){
if(!vis[i]){
p[++cnt]=i;
num[i]=1;
}
for(int j=1;j<=cnt&&p[j]*i<=n;j++){
vis[p[j]*i]=1;
if(i%p[j]==0){
num[p[j]*i]=num[i];
break;
}else num[p[j]*i]=num[i]+1;
}
}
for(int i=1;i<=n;i++)
f[i]=(f[i-1]+(1ll<<num[i]))%mod;
}
int F[maxn];
int f_(ll x){
if(x<=chr) return f[x];
if(~F[N/x]) return F[N/x];
ll ans=0;
for(ll i=1;i<=x;){
ll j=x/(x/i);
ans+=x/i*(1+j-i)%mod;
ans%=mod;
i=j+1;
}
for(ll i=2;i*i<=x;i++) (ans-=f_(x/(i*i)))%=mod;
return F[N/x]=ans;
}
int MAIN(){
// file();
cin>>N;gt(chr);memset(F,-1,sizeof F);
ll ans=0;
for(ll i=1;i<=N;"chr"){
ll j=N/(N/i);
(ans+=(ll)f_(N/i)*(j-i+1)%mod)%=mod;
i=j+1;
}
N%=mod;
cout<<((N*N-ans)%mod+mod)%mod<<endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!