866. 试除法判定质数 - AcWing题库
时间复杂度是logN
#include
using namespace std;
int n;
bool isprime(int x)
{
if(x<2) return false;
for(int i=2;i<=x/i;i++)
{
if(x%i==0) return false;
}
return true;
}
signed main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
if(isprime(x)) puts("Yes");
else puts("No");
}
return 0;
}
867. 分解质因数 - AcWing题库
#include
using namespace std;
int n;
void divide(int x)
{
for(int i=2;i<=x/i;i++)
{
if(x%i==0)
{
int s=0;
while(x%i==0) x/=i,s++;
cout<1) cout<>n;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
divide(x);
}
return 0;
}
868. 筛质数 - AcWing题库
#include
using namespace std;
const int N=1e6+10;
bool st[N];
int prime[N],cnt;
int n;
void getprimes(int x)
{
for(int i=2;i<=x;i++)
{
if(st[i]) continue;
prime[cnt++]=i;
for(int j=i+i;j<=x;j+=i) st[j]=true;
}
}
signed main()
{
cin>>n;
getprimes(n);
cout<
868. 筛质数 - AcWing题库
线性筛把时间复杂度优化到O(n),就需要保证筛去一个数只用一次,保证最小质因数就可以确保这一点。
如。筛去24,24=2*12,24=3*8,显然这里2是最小质因数,如何确保不筛去3*8?
这里3*8=3*2*4,即i包含上一个prime,直接break。
只要i包含了prime就不能保证最小质因数!!
#include
using namespace std;
const int N=1e6+10;
bool st[N];
int prime[N],cnt;
int n;
void getprimes(int x)
{
for(int i=2;i<=x;i++)
{
if(!st[i]) prime[cnt++]=i;
for(int j=0;prime[j]<=x/i;j++)
{
st[prime[j]*i]=true;
if(i%prime[j]==0) break;
}
}
}
signed main()
{
cin>>n;
getprimes(n);
cout<
869. 试除法求约数 - AcWing题库
#include
using namespace std;
void solve(int x)
{
stack s;
for(int i=1;i<=x/i;i++)
{
if(x%i==0)
{
cout<>n;
while(n--)
{
int x;
cin>>x;
solve(x);
}
return 0;
}
870. 约数个数 - AcWing题库
#include
using namespace std;
const int mod=1e9+7;
typedef long long LL;
signed main()
{
int n;
cin>>n;
unordered_map mp;
while(n--)
{
int x;
cin>>x;
for(int i=2;i<=x/i;i++)
{
while(x%i==0)
{
mp[i]++;
x/=i;
}
}
if(x>1) mp[x]++;
}
LL res=1;
for(auto p:mp) res=res*(p.second+1)%mod;
cout<
871. 约数之和 - AcWing题库
#include
using namespace std;
const int mod=1e9+7;
typedef long long LL;
signed main()
{
int n;
cin>>n;
unordered_map mp;
while(n--)
{
int x;
cin>>x;
for(int i=2;i<=x/i;i++)
{
while(x%i==0)
{
mp[i]++;
x/=i;
}
}
if(x>1) mp[x]++;
}
LL res=1;
for(auto p:mp)
{
LL a=p.first,b=p.second;
LL t=1;
while(b--) t=(t*a+1)%mod;//秦九韶
res=res*t%mod;
}
cout<
872. 最大公约数 - AcWing题库
#include
using namespace std;
int gcb(int a,int b)
{
return b?gcd(b,a%b):a;
}
signed main()
{
int n;
cin>>n;
while(n--)
{
int a,b;
cin>>a>>b;
cout<
873. 欧拉函数 - AcWing题库
#include
using namespace std;
signed main()
{
int n;
cin>>n;
while(n--)
{
int x;
cin>>x;
int res=x;
for(int i=2;i<=x/i;i++)
{
if(x%i==0)
{
res=res/i*(i-1);
while(x%i==0) x/=i;
}
}
if(x>1) res=res/x*(x-1);
cout<
874. 筛法求欧拉函数 - AcWing题库
#include
using namespace std;
const int N=1e6+10;
int prime[N],cnt;
bool st[N];
int phi[N];//欧拉函数
typedef long long LL;
signed main()
{
int n;
cin>>n;
phi[1]=1;
for(int i=2;i<=n;i++)
{
if(!st[i])
{
prime[cnt++]=i;
phi[i]=i-1;//质数的欧拉函数
}
for(int j=0;prime[j]<=n/i;j++)
{
st[prime[j]*i]=true;
if(i%prime[j]==0)
{
phi[prime[j]*i]=prime[j]*phi[i];
//括号里质因子是一样的,只是n要多乘上一个
break;
}
phi[prime[j]*i]=phi[i]*(prime[j]-1);
//prime是质数且i不能整除prime,则说明两数没有公因数
//那么prime[j]*i比i只是多了一个质因子prime[j]
}
}
LL res=0;
for(int i=1;i<=n;i++) res+=phi[i];
cout<
875. 快速幂 - AcWing题库
#include
using namespace std;
typedef long long LL;
LL qmi(int a,int b,int p)
{
LL res=1%p;
while(b)
{
if(b&1) res=res*(LL)a%p;
a=a*(LL)a%p;
b>>=1;
}
return res;
}
signed main()
{
int n;
cin>>n;
while(n--)
{
int a,b,p;
cin>>a>>b>>p;
cout<
876. 快速幂求逆元 - AcWing题库
(1)当a与p互质时,用快速幂求逆元(费马小定理):quick_power(a, b, p);
(2)当a与p不互质时,用扩展欧几里得算法求逆元:exgcd(a, p, x, y)。
概念:
证明:费马小定理(通俗易懂) - 知乎 (zhihu.com)
#include
using namespace std;
typedef long long LL;
LL qmi(int a,int b,int p)
{
LL res=1%p;
while(b)
{
if(b&1) res=res*(LL)a%p;
a=a*(LL)a%p;
b>>=1;
}
return res;
}
signed main()
{//当a和p不互质时无解,由于p是质数,也就只有a是p的倍数时无解
int n;
cin>>n;
while(n--)
{
int a,b,p;
cin>>a>>p;
if(a%p==0) puts("impossible");
else cout<
877. 扩展欧几里得算法 - AcWing题库
主要是递归。先正着求出gcd的值,求完之后倒着求x,y。
AcWing 877. 扩展欧几里得算法 - AcWing
#include
using namespace std;
int exgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1,y=0;
return a;
}
int x1,y1,gcd;
gcd=exgcd(b,a%b,x1,y1);
x=y1,y=x1-a/b*y1;
return gcd;
}
signed main()
{
int n;
cin>>n;
while(n--)
{
int a,b,x,y;
cin>>a>>b;
exgcd(a,b,x,y);
cout<
878. 线性同余方程 - AcWing题库
想不明白主要应该是不太清楚裴属定理,看这个:裴蜀定理 - OI Wiki (oi-wiki.org)
#include
using namespace std;
typedef long long LL;
int exgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1,y=0;
return a;
}
int x1,y1,gcd;
gcd=exgcd(b,a%b,x1,y1);
x=y1,y=x1-a/b*y1;
return gcd;
}
signed main()
{
int n;
cin>>n;
while(n--)
{
int a,b,m;
cin>>a>>b>>m;
int x,y;
int d=exgcd(a,m,x,y);
if(b%d) puts("impossible");
else cout<<(LL)b/d*x%m<
204. 表达整数的奇怪方式 - AcWing题库
基础中国剩余定理:算法学习笔记(10): 中国剩余定理 - 知乎 (zhihu.com)
好难,明天再看
883. 高斯消元解线性方程组 - AcWing题库
#include
using namespace std;
const int N=110;
const double eps = 1e-8;
int n;
double a[N][N];
int gauss() // 高斯消元,答案存于a[i][n]中,0 <= i < n
{
int c,r;//列,行
for(c=0,r=0;c fabs(a[t][c]) ) t=i;//把最大的换上去
}
if(fabs(a[t][c])=c;i--) a[r][i]/=a[r][c]; //首位变成1
for(int i=r+1;ieps)
{
for(int j=n;j>=c;j--)
{
a[i][j]-=a[r][j]*a[i][c];
}
}
}
r ++ ;
}
if(reps) return 2;//无解
}
return 1; //无穷解
}
//只有一解
for(int i=n-1;i>=0;i--)
{
for(int j=i+1;j>n;
for(int i=0;i>a[i][j];
}
}
int t=gauss();
if (t == 2) puts("No solution");
else if (t == 1) puts("Infinite group solutions");
else
{
for (int i = 0; i < n; i ++ )
printf("%.2lf\n", a[i][n]);
}
return 0;
}
从1开始存的版本。
#include
using namespace std;
const int N=110;
const double eps=1e-8;
int n;
double a[N][N];
int gauss()
{
int r=1,c=1;//行列,r<=n,c<=n+1
for(r=1,c=1;c<=n;c++) //遍历每一列
{
int t=r;//记录行
for(int i=t;i<=n;i++)
{
if(fabs(a[i][c]>fabs(a[t][c]))) t=i;
}
if(fabs(a[t][c])=c;i--) a[r][i]/=a[r][c];
for(int i=r+1;i<=n;i++)//对每一行
{
if(fabs(a[i][c])=c;j--)
{
a[i][j]-=a[r][j]*a[i][c];
}
}
r++;
}
if(reps) return 0;//无解
}
return 2;//无穷解
}
for(int i=n-1;i>=1;i--)
{
for(int j=i+1;j<=n+1;j++)
{
a[i][n+1]-=a[j][n+1]*a[i][j];
}
}
return 1;
}
signed main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n+1;j++)
{
cin>>a[i][j];
}
}
int t=gauss();
if(t==0) puts("No solution");
else if(t==2) puts("Infinite group solutions");
else
{
for(int i=1;i<=n;i++) printf("%.2lf\n",a[i][n+1]);
}
return 0;
}
884. 高斯消元解异或线性方程组 - AcWing题库
#include
using namespace std;
const int N=110;
int n;
int a[N][N];
void guass()
{
int r,c;
for(r=1,c=1;c<=n;c++)//枚举列
{
int t=r;
for(int i=r;i<=n;i++)
{
if(a[i][c])
{
t=i;
break;
}
}
if(a[t][c]==0) continue;//说明第c列都是0
for(int i=c;i<=n+1;i++) swap(a[r][i],a[t][i]);
for(int i=r+1;i<=n;i++)
{
if(a[i][c]==0) continue;
for(int j=c;j<=n+1;j++)
{
a[i][j]^=a[r][j];
}
}
r++;
}
if(r=1;i--)
{
for(int j=i+1;j<=n+1;j++)
{
a[i][n+1]^=a[i][j]*a[j][n+1];
}
}
for(int i=1;i<=n;i++)
{
cout<>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n+1;j++)
{
cin>>a[i][j];
}
}
guass();
return 0;
}
885. 求组合数 I - AcWing题库
1<=b<=a<=2000
#include
using namespace std;
const int N=2010,mod=1e9+7;
int a[N][N];
void init()
{
for(int i=0;i>n;
while(n--)
{
int c,b;
cin>>c>>b;
cout<
886. 求组合数 II - AcWing题库
1<=b<=a<=1e5
#include
using namespace std;
typedef long long LL;
const int N=1e5+10,mod=1e9+7;
int fact[N],infact[N];
int qmi(int a,int k,int p)
{
int res=1;
while(k)
{
if(k&1) res=(LL)res*a%p;
a=(LL)a*a%p;
k>>=1;
}
return res;
}
signed main()
{
fact[0]=infact[0]=1;
for(int i=1;i>n;
while(n--)
{
int a,b;
cin>>a>>b;
cout<<(LL)fact[a]*infact[b]%mod*infact[a-b]%mod<