这个题是一个基于线性筛的dp
如果p是素数那么
d
p
[
p
]
=
p
+
1
dp[p]=p+1
dp[p]=p+1
如果
i
i
i%
p
!
=
0
p!=0
p!=0
那么
d
p
[
i
∗
p
]
=
d
p
[
i
]
+
d
p
[
i
]
∗
p
dp[i*p]=dp[i]+dp[i]*p
dp[i∗p]=dp[i]+dp[i]∗p因为因为增加了一个因子,因此这个因子数*2,所以要加上全部因子乘上这个质数刚好就是答案
如果
i
i
i%
p
=
=
0
p==0
p==0
那么
d
p
[
i
∗
p
]
=
d
p
[
i
]
+
(
d
p
[
i
]
−
d
p
[
i
/
p
]
)
∗
p
dp[i*p]=dp[i]+(dp[i]-dp[i/p])*p
dp[i∗p]=dp[i]+(dp[i]−dp[i/p])∗p后边的dp[i/p]之前乘过p,如果现在只对dp[i]*p的话那就会出现重复的情况,因为之前做过的运算现在又做了一遍,因此要减去之前乘过的。
SIGFPE 浮点运算错误~
#include<iostream>
using namespace std;
typedef long long ll;
const int N=1e7+1000;
int primes[N], cnt; // primes[]存储所有素数
bool st[N]; // st[x]存储x是否被筛掉
ll dp[N];
int ans[N];
void get_primes(int n)
{
for (int i = 2; i <= n; i ++ )
{
if (!st[i]){
primes[cnt ++ ] = i;
dp[i]=i+1;
}
for (int j = 0; primes[j] <= n / i; j ++ )
{
st[primes[j] * i] = true;
if (i % primes[j] == 0){
dp[primes[j] * i]=dp[i]+(dp[i]-dp[i/primes[j]])*primes[j];
break;
} else{
dp[primes[j]*i]=dp[i]+dp[i]*primes[j];
}
}
}
}
int main(){
dp[1]=1;
get_primes(1e7);
for(ll i=1;i<=1e7;i++){
if(dp[i]<=1e7){
if(!ans[dp[i]])ans[dp[i]]=i;
// else ans[dp[i]]=min(ans[dp[i]],i);
}
}
//cout<<dp[18]<<endl;
//for(ll i=1;i<=50;i++)cout<<dp[i]<<endl;
int T;
cin>>T;
while(T--){
int t;
scanf("%d",&t);
if(ans[t]==0)cout<<"-1"<<endl;else
cout<<ans[t]<<endl;
}
}