数学基础:
目录:
P1226 【模板】快速幂||取余运算
P1595 信封问题
P3383 【模板】线性筛素数
P3811 【模板】乘法逆元
P1226 【模板】快速幂||取余运算
生日这天又写了一次!!
祝自己生日快乐!!
#include<iostream>
using namespace std;
#define ll long long
ll b,p,k,ans = 1;
int main()
{
cin>>b>>p>>k;
cout<<b<<"^"<<p<<" mod "<<k<<"=";
while(p > 0)
{
if(p & 1) ans = ans* b % k;
b = b * b % k;
p>>=1;//将B的二进制向右移
}
cout<<ans % k<<" ";
return 0;
}
P1595 信封问题
思路:直接套公式,山东老师告诉我的这个结论
//错排问题P1595
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 25;
ll f[N];
int main()
{
int n;
cin>>n;
f[0] = 1;
f[1] = 0;
for(int i = 2;i <= n;i++)
f[i] = (i-1) * (f[i-1] + f[i-2]);//循环过程中只有一次运算,所以这里不要加括号,会WA
//以及这里是公式,记住就行,很好记的
cout<<f[n]<<" ";
return 0;
}
P3383 【模板】线性筛素数
思路:常见的不就那两个筛,一个是埃氏筛,另外一个是欧拉筛
这题果断欧拉,数据范围在1e8,埃氏筛时间复杂度:O(nloglogn);而欧拉是O(n)
#include<bits/stdc++.h>
using namespace std;
const int N = 1e8+10;
int Prime[N];//用来存数组的
bool is_prime[N];
int n,q;
void oulashai(int n)
{
int cnt = 0;
memset(is_prime,true,sizeof(is_prime));
is_prime[0] = is_prime[1] = 0;
for(int i = 2;i <= n;i++)
{
if(is_prime[i]) Prime[++cnt] = i;
for(int j = 1;(j <= cnt) && (i*Prime[j]) <=n;j++)//欧拉筛必须从1开始
{
is_prime[i * Prime[j]] = 0;
if(i % Prime[j] == 0) break;
}
}
return;
}
int main()
{
cin>>n>>q;
oulashai(n);
while(q--)
{
int k;
cin>>k;
cout<<Prime[k]<<endl;
}
return 0;
}
埃氏我也补充一下:
#include<bits/stdc++.h>
using namespace std;
int n,q;
const int N = 1e8+10;
bool is_prime[N];
int a[N];
//埃氏筛
void anshishai(int n)
{
int cnt = 0;
for(int i = 0;i <= n;i++)is_prime[i] = true;
is_prime[0] = is_prime[1] = 0;
for(int i = 1;i <= n;i++)
{
if(is_prime[i])
{
a[++cnt] = i;
if(i * i > n)continue;
for(int j = 2 * i;j <= n;j+=i)is_prime[j] = false;
}
}
}
int main()
{
cin>>n>>q;
anshishai(n);
while(q--)
{
int k;
cin>>k;
cout<<a[k]<<endl;
}
return 0;
}
P3811 【模板】乘法逆元
思路:直接递推公式即可
#include<iostream>
using namespace std;
#define ll long long
//扩展欧几里得求逆元
//void exgcd(int a,int b,int &x,int &y)
//{
// if(b == 0)
// {
// x = 1,y = 0;
// }
// int gcd = exgcd(b,a % b,y,x);
// y -= (a/b) * x;
//}
//int _inv(int a,int b)
//{
// int x = 1,y = 0;
// exgcd(a,p,x,y);
// return (x % p + p) % p;
//}
const int N = 3e6+10;
ll n,p;
ll inv[N];
int main()
{
scanf("%lld%lld",&n,&p);
inv[1] = 1;
printf("%lld\n",inv[1]);
for(int i = 2;i <= n;i++)
{
inv[i] = (ll)(-(p/i) * inv[p % i]);
inv[i] = (ll)(inv[i] % p + p) % p;
printf("%lld\n",inv[i]);
}
return 0;
}