cf1512 G - Short Task
题意:
给一个c,求n,使得n的因数和为c
题解:
求因数和的裸题
我们直接预处理所有数的因数和
筛法求因数和
讲解博客
代码:
埃式筛nloglog(1e7) 1500+ms
#include<bits/stdc++.h>
#define debug(x,y) printf("%s = %d\n",x,y);
typedef long long ll;
using namespace std;
inline int read(){int s=0,w=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);return s*w;
}
const int maxn=1e7+9;
ll p[maxn];
ll num[maxn];
int main()
{num[0]=0;memset(p,-1,sizeof(p));for(int i=1;i<=maxn;i++){for(int j=i;j<maxn;j+=i){num[j]+=i;//i是j的因子 }}for(int i=1;i<maxn;i++){if(num[i]>maxn)continue;if(p[num[i]]==-1){p[num[i]]=i;}} int t;t=read();while(t--){int c;c=read();cout<<p[c]<<endl;}return 0;
}
线性筛:
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e7+5;
typedef int LL;
inline LL read(){LL x=0,f=1;char ch=getchar(); while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
int l,r;
int prime[maxn],f[maxn],v[maxn],cnt;
//f[i]:i的因数和,v[i]:i的最小质因数p
bool vis[maxn];
int ans[maxn];
void Euler()
{ans[1]=1;for(LL i=2;i<=r;i++){if(!vis[i]){prime[++cnt]=i;f[i]=v[i]=i+1;//i是质数 vis[i]=1;}for(LL j=1;j<=cnt&&prime[j]<=r/i;j++){vis[i*prime[j]]=1;if(i%prime[j]==0){v[i*prime[j]]=v[i]*prime[j]+1;f[i*prime[j]]=f[i]/v[i]*v[i*prime[j]];break;}else{v[i*prime[j]]=prime[j]+1;f[i*prime[j]]=f[i]*f[prime[j]];}}}
}
int main(){memset(ans,-1,sizeof(ans));r=1e7+5;Euler();for(LL i=1;i<=r;i++){if(f[i]>1e7) continue;if(ans[f[i]]==-1){ans[f[i]]=i;}}int t;scanf("%d",&t);while(t--){int x;scanf("%d",&x);printf("%d\n",ans[x]);}return 0;
}