目录
欧拉筛法模板
int tot = 0;
bool vis[maxn*10];
int prime[maxn];
void is_prime(int n)
{
for(int i=2;i<=n;i++)
{
if(!vis[i])
prime[tot++] = i;
for(int j=0;i*prime[j]<=n;j++) {
vis[i*prime[j]] = 1;
if(i%prime[j]==0)
break;
}
}
}
质因数分解模板
int p[maxn],c[maxn];
void divide(int n) {
int tot = 0;
for(int i=2;i<=sqrt(n);i++) {
if(n%i==0) {
p[++tot] = i;
c[tot] = 0;
while(n%i==0) {
n /= i;
c[tot]++;
}
}
}
if(n>1) p[++tot] = n, c[tot] = 1; //n为质数
for(int i=1;i<=tot;i++) {
cout<<p[i]<<" "<<c[i]<<endl;
}
}
poj2689 Prime Distance
题目链接
http://poj.org/problem?id=2689
题意
给定两个整数 L,R , , 求闭区间[L,R]内质数的差最大为多少。
题解
由于R-L并不大,所以可以先生成 2~ 内所有的质数,然后对每个质数,生成[L,R]区间内所有的合数。然后筛选出[L,R]区间内的质数即可。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <cmath>
using namespace std;
#define INIT(x) memset(x,0,sizeof(x))
#define eps 1e-8
#define next next_
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x7fffffff;
const int inf = 0x3f3f3f3f;
const int maxn = 1000005;
const int N = 105;
inline void read(int &x) {
int f=1;x=0;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
x*=f;
}
int l,r;
int tot = 0;
bool vis[1000005],flag[1000005];
int prime[maxn],e[maxn];
void is_prime(int n)
{
for(int i=2;i<=n;i++)
{
if(!vis[i])
prime[tot++] = i;
for(int j=0;i*prime[j]<=n;j++) {
vis[i*prime[j]] = 1;
if(i%prime[j]==0)
break;
}
}
}
inline void check(int x,int l,int r) {
for(int i=l/x;i<=r/x;i++) {
if(i>1) flag[x*i-l] = 1; //-l,这样就不会越界
}
}
int main()
{
while(~scanf("%d%d",&l,&r)) {
INIT(vis), INIT(prime), INIT(flag), INIT(e);
tot = 0;
if(l==1) l++;
is_prime(sqrt(r));
for(int i=0;i<tot;i++) {
check(prime[i],l,r);
}
int tot2=0;
for(int i=l;i<=r;i++) {
if(!flag[i-l]) {
e[tot2++] = i;
}
if(i==r) break; //要命,到了2147483647后i还会+1,溢出成负的
}
int k1_1,k1_2,k2_1,k2_2,maxi=-1,mini=INF;
bool flag1=0;
for(int i=1;i<tot2;i++) {
if(e[i]-e[i-1]>maxi) {maxi=e[i]-e[i-1];k1_1=e[i-1];k1_2=e[i];flag1=1;}
if(e[i]-e[i-1]<mini) {mini=e[i]-e[i-1];k2_1=e[i-1];k2_2=e[i];flag1=1;}
}
if(!flag1) cout<<"There are no adjacent primes."<<endl;
else cout << k2_1 << ',' << k2_2 << " are closest, " << k1_1 << ',' << k1_2 << " are most distant.\n";
}
return 0;
}
CH3101 阶乘分解
题目链接
题意
将n!分解质因数。
题解
对于每一个质因子p,1-n中含有p的数的个数为n/p, 含有的个数为个,但是有一个已经计过一次了,所以为个,依此类推。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <cmath>
using namespace std;
#define INIT(x) memset(x,0,sizeof(x))
#define eps 1e-8
#define next next_
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x7fffffff;
const int inf = 0x3f3f3f3f;
const int maxn = 200005;
const int N = 105;
inline void read(int &x) {
int f=1;x=0;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
x*=f;
}
int n,prime[maxn];
bool vis[maxn*10];
int tot = 0;
void is_prime(int n) {
for(int i=2;i<=n;i++) {
if(!vis[i]) prime[tot++] = i;
for(int j=0;i*prime[j]<=n;j++) {
vis[i*prime[j]] = 1;
if(i%prime[j]==0) break;
}
}
}
int solve(int x) {
int res = 0;
int p = x;
for(int i=1;i<=log(n)/log(p);i++) {
res += n/x;
x *= p;
}
return res;
}
int main()
{
cin>>n;
is_prime(n);
for(int i=0;i<tot;i++) {
int ans = solve(prime[i]);
cout<<prime[i]<<" "<<ans<<endl;
}
return 0;
}