1. 试除法
模板:复杂度 O(sqrt(n))
void solve(int n){
for(int i=2;i<=n/i;i++){
if(n%i==0){
int sum=0;
while(n%i==0){
n/=i;
sum++;
}
cout<<i<<" "<<sum<<endl;
}
}
if(n>1) cout<<n<<" "<<1<<endl;
}
1.普通筛
模板:复杂度 O(n*logn)
int n,prime[N],p[N],cnt;
void solve(){
for(int i=2;i<=n;i++){
if(prime[i]==0){
p[++cnt]=i;
for(int j=2;j*i<=n;j++) prime[j*i]=1;
}
}
}
2.线性筛
模板:复杂度 O(n)
int n,prime[N],p[N],cnt;
void solve(){
for(int i=2;i<=n;i++){
if(prime[i]==0) p[++cnt]=i;
for(int j=1;j<=cnt&&i*p[j]<=n;j++){
prime[i*p[j]]=1;
if(i%p[j]==0) break;
}
}
}
模板:
LL qp(LL a,LL b){
//是求a的b次方
LL ans=1ll%mod,base=a%mod;//ans为答案,base为a^(2^n)
while(b>0){
if(b&1ll) ans=(ans*base)%mod;
base=(base*base)%mod;
b>>=1ll;
}
return ans;
}
同余不满足除法,即 (a/b) % p != (a % p) / (b % p) ;
这里主要说明分数取模的方法,对于 (a/b) % p,可以先求出 b 在 % p 下的逆元,然后乘上a,再mod p,就是分数取模的值了;
逆元的求解方法:
1.费马小定理
当 p 为素数,且 a 为正整数,并且 a,p 互质,则逆元就等于 a p − 2 a^{p-2} ap−2%p;
所以只要运用快速幂就可以;
模板题:洛谷·P2613 【模板】有理数取余
模板:
LL qp(LL a,LL b){
//是求a的b次方
LL ans=1ll%mod,base=a%mod;//ans为答案,base为a^(2^n)
while(b>0){
if(b&1ll) ans=(ans*base)%mod;
base=(base*base)%mod;
b>>=1ll;
}
return ans;
}
int main(){
string s1,s2;cin>>s1>>s2;
LL a=0,b=0;
int len1=s1.length(),len2=s2.length();
for(int i=0;i<len1;i++){
a*=10;a+=s1[i]-'0';
a%=mod;
}
for(int i=0;i<len2;i++){
b*=10;b+=s2[i]-'0';
b%=mod;
}
if(b==0) cout<<"Angry!"<<endl;
else{
LL ans=a*qp(b,mod-2ll);
cout<<(ans%mod+mod)%mod<<endl;
}
return 0;
}
扩展欧几里得是用来求 ax + by = gcd(a,b) 中的未知数的,那么如果等式不等于 gcd(a,b) 怎么办呢?
比如:ax + by = z,记住一点就是等式有解必须保证 z%gcd(a,b)==0,所以可以先利用扩展求出 ax + by = gcd(a,b) 的解,然后乘上 z/gcd(a,b) 就可以;
模板题:洛谷·P1082 同余方程
模板:
LL x,y;//方程的解
void exgcd(LL a,LL b){
if(b==0){
x=1,y=0;
return;
}
exgcd(b,a%b);
LL tx=x;
x=y;
y=tx-a/b*y;
}
int main(){
LL a,b;cin>>a>>b;
exgcd(a,b);
x=(x%b+b)%b;//求出来的x一定满足方程,但不一定是最小解
cout<<x<<endl;
return 0;
}
求组合数 C ( n , m ) C(n,m) C(n,m);
模板:
LL qp(LL a,LL b){
//是求a的b次方
LL ans=1ll%mod,base=a%mod;//ans为答案,base为a^(2^n)
while(b>0){
if(b&1ll) ans=(ans*base)%mod;
base=(base*base)%mod;
b>>=1ll;
}
return ans;
}
LL fact[N];
LL inv[N];
void init(){
fact[0] = 1;
for(int i = 1;i < N ;i ++)
fact[i] = fact[i - 1] * i % mod;
inv[N - 1] = qp(fact[N - 1], mod - 2);
for(int i = N - 2; i >= 0; i --)
inv[i] = inv[i + 1] * (i + 1) % mod;
}
LL C(LL x, LL y){
if(x < y || y < 0)
return 0;
return fact[x] * inv[y] % mod * inv[x - y] % mod;
}
int main(){
init();
cout<<C(100,2);
return 0;
}