很久之前的周赛做了一道题目:D 问就是太懒
题面如下:
题目的意思呢,就是给你一个c让你找到一个n,使c = n的因数之和;
数值范围1~1e7,只要胆子大就能过 当然一开始胆子小了。
这是后来补题的
AC代码:
第一步用a[i]来储存i的因数和;
for(int i=1;i<=10000000;i++)
{
for(int j=1;i*j<=10000000;j++)
a[i*j]+=i;
}
第二步用数组ans[a[i]]来确定对应的最小n
for(int i=1;i<=10000000;i++)
{
if(a[i]>1e7)continue;//不加会越界 re
if(ans[a[i]]==0)ans[a[i]]=i;
else ans[a[i]]=min(ans[a[i]],i);
}
完整代码如下:
#include<bits/stdc++.h>
using namespace std;
int a[10000010];
int ans[10000010];
int main()
{
for(int i=1;i<=10000000;i++)
{
for(int j=1;i*j<=10000000;j++)
a[i*j]+=i;
}
for(int i=1;i<=10000000;i++)
{
if(a[i]>1e7)continue;//不加会越界 re
if(ans[a[i]]==0)ans[a[i]]=i;
else ans[a[i]]=min(ans[a[i]],i);
}
int t;
cin>>t;
while(t--)
{
int c;
cin>>c;
if(ans[c]==0)cout<<"-1\n";
else cout<<ans[c]<<"\n";
}
}
说实话第一次做这个题目的时候没想起来之前数论学的筛法hhh,后来得到学长提示才想起来去把之前学的数论复习一下
30min之后~。。。。
在洛谷上找了道题来检验一下欧筛的学习成果
*洛谷 P3383 线性筛素数
*欧拉筛
#include <cstdio>
#include <cstring>
bool isPrime[100000010];
//isPrime[i] == 1表示:i是素数
int Prime[10000010], cnt = 0;
//Prime存质数
void GetPrime(int n)//筛到n
{
memset(isPrime, 1, sizeof(isPrime));
//以“是素数”为初始状态,逐个删去
isPrime[1] = 0;//1不是素数
for(int i = 2; i <= n; i++)
{
if(isPrime[i])//没筛掉
Prime[++cnt] = i; //i成为下一个素数
for(int j = 1; j <= cnt && i*Prime[j] <= n; j++)
{
//从Prime[1],即最小质数2开始,逐个枚举已知的质数,并期望Prime[j]是(i*Prime[j])的最小质因数
//当然,i肯定比Prime[j]大,因为Prime[j]是在i之前得出的
isPrime[i*Prime[j]] = 0;
if(i % Prime[j] == 0)//i中也含有Prime[j]这个因子
break;
}
}
}
int main()
{
int n, q;
cin>>n>>q;
GetPrime(n);
while (q--)
{
int k;
cin>>k;
cin>>Prime[k];
}
return 0;
}
欧拉筛法的时间是埃式筛法的1/10,因为它不会重复标记一个数是不是素数的倍数;