数学备忘录


//数学备忘录

//数学

//素数

//判定素数

bool Is_prime(int n)
{
   if(n==1) return false;
   if(n==2||n==3) return true;
   if(n%6!=1&&n%6!=5) return false;
   for(register int i=5;i*i<=n;i+=6)
       if(n%i==0||n%(i+2)==0) return false;
   return true;
}
//素数线性筛
const int MAXN=1e5+100;//MAXN<=n
int check[MAXN];//标记合数
int prime[MAXN];//存放筛出的素数   不超过N的质数约有N/ln N个

void getprime(int n)//线性筛出2~n范围内的素数
{
//memset(check,0,sizeof(check));
   // for(int i=0;i<=n;i++) check[i]=0;
    check[0]=check[1]=1;
int tot=0;//记录素数的个数

for(int i=2;i<=n;i++){
if(check[i]==0) prime[++tot]=i;

for(int j=1;j<=tot;j++){
if(i*prime[j]>n) break;
check[i*prime[j]]=1;
if(i%prime[j]==0) break;
}
}
}
//埃式素数筛
const int MAXN=1e5+100;
int prime[MAXN];   //存放筛出的素数 不超过N的质数约有N/ln N个
int check[MAXN];   //标记合数
void find_prime(int n)
{
//memset(check,1,sizeof(check));
//for(int i=0;i<=n;i++) check[i]=0;
   //check[0]=check[1]=1;
   
   int tot=0;

   for(int i=2;i<=n;i++){
       if(check[i]==0){
           prime[++tot]=i;
           for(int j=2*i;j<=n;j+=i) check[j]=1;
      }
  }
}
//质因数分解,只适合比较小的数
const int MAXN=1e5+100;
int p[MAXN];
int c[MAXN];
void divide(int n)
{
int m=0;
for(int i=2;i<=sqrt(n);i++){
if(n%i==0){
p[++m]=i,c[m]=0;
while(n%i==0) n/=i,c[m]++;
}
}
if(n>1) p[++m]=n,c[m]=1;
for(int i=1;i<=m;i++) cout<<p[i]<<'^'<<c[i]<<endl;

}
//区间素数筛法
# include <bits/stdc++.h>
using namespace std;

const int MAXN=1e5+100;
const int MAXX=1e6+100;
typedef long long LL;
int check[MAXN];
int prime[MAXN];
int vis[MAXX];
int tot;
void getprime(int n)//线性素数筛,筛出 2-sqrt(r)范围内的素数,(任何一个合数n必定包含一个不超过sqrt(n)的质因子)
{
memset(check,0,sizeof(check));

for(int i=2;i<=n;i++){
if(check[i]==0) prime[++tot]=i;
for(int j=1;j<=tot;j++){
if(i*prime[j]>n) break;
check[i*prime[j]]=1;
if(i%prime[j]==0) break;
}
}
}
int main()
{
getprime(1e5);

LL l,r;

while(~scanf("%lld %lld",&l,&r)){
memset(vis,0,sizeof(vis));//对于区间内的,能够被所筛出的素数整除的剔除
for(int i=1;i<=tot;i++){
LL a=(l+prime[i]-1)/prime[i];
LL b=r/prime[i];
for(int j=max(2,a);j<=b;j++) vis[j*prime[i]-l]=1;
}

if(l==1) vis[0]=1;//特判断区间左端为1的情况
//当前已经把区间中的合数全被筛完了剩下的就是区间里的素数
/*
LL cnt=-1,maxx=0,maxa=0,maxb=0,minn=1e6+100,mina=0,minb=0;
for(int i=r-l;i>=0;i--){
if(vis[i]==0){
if(cnt!=-1){
int d=cnt-(l+i);
if(d>=maxx){
maxa=l+i;
maxb=cnt;
maxx=d;
}
if(d<=minn){
mina=l+i;
minb=cnt;
minn=d;
}
}
cnt=i+l;
}
}

if(maxa&&maxb&&mina&&minb){
cout<<mina<<","<<minb<<" are closest, "<<maxa<<","<<maxb<<" are most distant."<<endl;
}else{
cout<<"There are no adjacent primes."<<endl;
}*/
}


return 0;
}
//阶乘分解
# include <bits/stdc++.h>
using namespace std;

const int MAXN=1e6+100;
int prime[MAXN];
int check[MAXN];
int tot=0;
typedef long long LL;
void getprime(int n)
{
for(int i=2;i<=n;i++){
if(check[i]==0) prime[++tot]=i;
for(int j=1;j<=tot;j++){
if(i*prime[j]>n) break;
check[i*prime[j]]=1;
if(i%prime[j]==0) break;
}
}
}
void solve(int n)
{
int cnt=0;

for(int i=1;i<=tot;i++){//对于每一个质数
cnt=0;
for(LL j=prime[i];j<=n;j*=prime[i])//保证每一个数中的p都除尽
cnt+=n/j;
printf("%d %d\n",prime[i],cnt);
}
}
int main()
{
int n;
scanf("%d",&n);

getprime(n);
solve(n);

return 0;
}

//约数

//求N的正约数集合
//试除法
# include <bits/stdc++.h>
using namespace std;

typedef long long LL;
LL n;
void factor(LL n)
{
for(int i=1;i*i<=n;i++){
if(n%i==0){
printf("%d ",i);
if(i!=n/i) printf("%d ",n/i);
}
}
return ;
}
int main()
{
scanf("%lld",&n);

factor(n);

return 0;
}
//倍数法
# include <bits/stdc++.h>
using namespace std;

const int MAXN=5e5+100;
typedef long long LL;
vector<LL> factor[MAXN];
void factor1(LL n)
{
for(int i=1;i<=n;i++){
for(int j=1;j<=n/i;j++){
factor[i*j].push_back(i);
}
}

for(int i=1;i<=n;i++){
for(int j=0;j<factor[i].size();j++){
printf("%lld ",factor[i][j]);
}
printf("\n");
}
return ;
}
LL n;
int main()
{
scanf("%lld",&n);

factor1(n);

return 0;
}
//dfs求分解质因数    原题:反素数
# include <bits/stdc++.h>
using namespace std;

typedef long long LL;
int n;
LL ans=2e9+100,cnt=0;
int prime[20]={1,2,3,5,7,11,13,17,19,23,29};
LL ccnt[20];
void dfs(int id,LL now)
{
if(id==11){
int cnt1=1;
for(int i=1;i<=10;i++) cnt1*=(ccnt[i]+1);/**/
if(cnt1>cnt){
cnt=cnt1;
ans=now;
}else if(cnt1==cnt&&ans>now){/**/
ans=now;
}
return ;
}

ccnt[id]=0;dfs(id+1,now);//对当前的质数不用来做约数
for(int i=1;i<=30;i++){
now=now*prime[id];
if(now>n) break;
ccnt[id]=i;
dfs(id+1,now);//在当前的基础上,再用别的质数做约数
}

return ;
}
int main()
{
scanf("%lld",&n);
dfs(1,1);
printf("%lld\n",ans);
return 0;
}

//互质与欧拉函数

//欧拉函数
int phi(int n)
{
int ans=n;
for(int i=2;i<=sqrt(n);i++){
if(n%i==0){
ans=ans/i*(i-1);
while(n%i==0) n/=i;
}
}
if(n>1) ans=ans/n*(n-1);

return ans;
}
//埃式筛法求欧拉函数
int phi[MAXN];
void solvephi(int n)
{
for(int i=2;i<=n;i++) phi[i]=i;
for(int i=2;i<=n;i++){
if(phi[i]==i){
for(int j=i;j<=n;j+=i){
phi[j]=phi[j]/i*(i-1);
}
}
}
return ;
}
//线性筛法求欧拉函数
int check[MAXN];
int prime[MAXN];
int phi[MAXN];
void solvephi(int n)
{
check[0]=check[1]=1;
int tot=0;
for(int i=2;i<=n;i++){
if(check[i]==0){
prime[++tot]=i;
phi[i]=i-1;
}
for(int j=1;j<=tot;j++){
if(i*prime[j]>n) break;
check[i*prime[j]]=1;
if(i%prime[j]==0){
phi[i*prime[j]]=phi[i]*prime[j];
break;
}else{
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
}
}
//求一个数的三分之一次
LL third(LL n){
LL l=1,r=(LL)pow(n*1.0, 1.0 / 3) + 1,mid;
while(l<=r){
mid=(l+r)>>1;
//cout<<"l="<<l<<" mid="<<mid<<" r="<<r<<endl;
if(mid*mid*mid==n) return mid;
else if(mid*mid*mid>n) r=mid-1;
else l=mid+1;
}
return -1;
}



posted @ 2022-02-26 23:16  fengzlj  阅读(30)  评论(0)    收藏  举报