18.12.11题解
素数个数(prime)
题目描述求{1,2,...,N} 中素数的个数。
输入
1 个整数 N 。
输出
1 个整数,表示素数的个数。
样例输入
10
样例输出
4
提示
对于 40% 的数据,1≤N≤106;
对于 80% 的数据,1≤N≤10 7;
对于 100% 的数据,1 ≤ N <6*10 7;
参考代码
#include <cassert>
#include <cstdio>
#include <cstring>
const int N = 100000000;
bool isPrime[N+1]; //数组较大开在外面 用来记录是否是素数
int primeCount, primes[5761455];
int main() {
freopen("prime.in","r",stdin);
freopen("prime.out","w",stdout);
int n;
assert(scanf("%d", &n) == 1); //判断输入是否符合规定
assert(1 <= n && n <= N);
memset(isPrime, true, sizeof(isPrime)); //将初始定义为1(即假设他们都是素数)
primeCount = 0;
for (int i = 2; i <= n; ++ i)
{
if (isPrime[i])
{
primes[primeCount ++] = i;
}
for (int j = 0; j < primeCount && i * primes[j] <= n; ++ j)
{
isPrime[i * primes[j]] = false; //两个数相乘后得到的数肯定不是素数标记
if (i % primes[j] == 0) //保证i>j 避免重复运算
{
break;
}
}
}
printf("%d ", primeCount);
return 0;
}
自己的代码
#include<cstdio>
#include<cstring>
using namespace std;
bool mark[6000000];
int main()
{
int n,j,k=0,h;
scanf("%d",&n);
memset(mark,true,sizeof(mark));
for(int i=2;i<=n;i++)
{
for(j=2;i * j <= n && i>=j;j++)
{
mark[i*j] = false;
}
}
for(int i = 2;i <= n;i++)
if( mark[i] == 1)
k++;
printf("%d",k);
return 0;
}
2、1103: 数学欧拉函数(phi)
题目描述
对正整数n,n的欧拉函数(即φ(N))是少于或等于n的数中与n互质的数的数目。例如φ(8)=4,因为1,3,5,7均和8互质。
输入
一行一个整数N。
输出
一行一个整数φ(N)
样例输入
8
样例输出
4
提示
对于70%的数据,有N<=1000
对于100%的数据,有N<=231-1
参考代码
#include<iostream>
#include<cstring>
using namespace std;
long long n,ans;
int main()
{
cin>>n;
ans=n;
int i=1;
while(n!=1)
{
i++;
if(n%i==0)
{
ans=ans/i*(i-1);
n=n/i;
}
while(n%i==0) n=n/i;
}
cout<<ans;
return 0;
}
自己的代码
#include<cstdio>
using namespace std;
long long n,m;
int main()
{
scanf("%lld",&n);
m=n;
int i=1;
while(n != 1)
{
i++; //每循环一次就加1
if(n % i == 0) //可以被除的开的话
{
m = m / i * (i-1);
n /= i;
}
while(n%i==0) n=n/i;
} //这里其实是一个递归
printf("%lld",m);
return 0;
}
公式:
就是这个公式
Euler(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn)
3、1631: NOIP 2012 同余方程(mod)
题目描述
求关于x的同余方程ax ≡ 1 (mod b)的最小正整数解。
输入
输入只有一行,包含两个正整数a, b,用一个空格隔开。
输出
输出只有一行,包含一个正整数x0,即最小正整数解。输入数据保证一定有解。
样例输入
3 10
样例输出
7
提示
对于40%的数据,2 ≤b≤ 1,000;
对于60%的数据,2 ≤b≤ 50,000,000;
对于100%的数据,2 ≤a, b≤ 2,000,000,000。
参考代码
#include<iostream>
using namespace std;
long long a,b,x,y;
void exgcd(long long a,long long b,long long &x,long long &y)
{
if(b==0)
{
x=1;
y=0;
return;
}
exgcd(b,a%b,x,y);
int z=x;
x=y;
y=z-y*(a/b);
}
int main()
{
cin>>a>>b;
exgcd(a,b,x,y);
cout<<(x%b+b)%b<<endl;
}
自己的代码(也是学习来的)
#include<cstdio>
using namespace std;
long long a,b,x,y;
void exgcd(long long a,long long b,long long &x,long long &y)
{
if(b==0)
{
x=1;
y=0;
return;
}
exgcd(b,a%b,x,y);
int z=x;
x=y;
y=z-y*(a/b);
}
int main()
{
scanf("%lld%lld",&a,&b);
exgcd(a,b,x,y);
printf("%lld",(x%b+b)%b)
}
是扩展gcd的应用