NOIP临近,,写写模板。。。
求逆元:
扩展欧几里得求逆元
适用范围:常数小,适合单个求逆元
限制:gcd(a,n)==1
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define FROP "inv"
#define LL long long
using namespace std;
int n=100,mod=1e9+7,inv[105];
void exgcd(int a,int b,int& d,int &x,int &y)
{
if(!b){d=a;x=1;y=0;}
else {exgcd(b,a%b,d,y,x);y-=x*(a/b);}
}
int main()
{
freopen(FROP".out","w",stdout);
for(int i = 1; i <= n; i++)
{
int d,x,y;
exgcd(i,mod,d,x,y);//i mod mod 的逆元
inv[i]=(x%mod+mod)%mod;
}
for(int i = 1; i <= n; i++)
printf("%d,",inv[i]);
return 0;
}
费马小定理求逆元
适用范围:若mod是,inv=a^(mod-2)
否则inv=a^(phi(mod)-1),,所有前提条件,a,与mod互素。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define FROP "inv"
#define LL long long
using namespace std;
int n=100,mod=1e9+7,inv[105];
int euler_phi(int n)
{
int ans=n;
int m= sqrt(n+0.5);
for(int i = 2; i <= m; 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 power(int a,int b)
{
if(!b)return 1;
if(b==1)return a;
int p=power(a,b/2);
p=(LL)p*p%mod;
if(b%2)return p*a%mod;
return p;
}
int main()
{
freopen(FROP".out","w",stdout);
int eul=euler_phi(mod);
for(int i= 1; i <= 100; i++)
{
printf("%d,",power(i,eul-1));
}
return 0;
}
线性求逆元
没有限制,,表示爱上线性求逆元了。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define FROP "inv"
#define LL long long
using namespace std;
int n=100,mod=1e9+7,inv[105];
int main()
{
freopen(FROP".out","w",stdout);
inv[1]=1;
for(int i = 2; i <= n; i++)
inv[i]=(LL)(mod-mod/i)*inv[mod%i]%mod;
for(int i = 1;i <= n; i++)
printf("%d,",inv[i]);
return 0;
}
gcd模板
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
筛法求素数
void sieve(int n)
{
int m = sqrt(n+0.5);
for(int i = 2; i <= m; i++)if(!vis[i])
for(int j = i*i; j <= n; j+=i)vis[j]=1;
}
int main()
{
freopen(FROP".in","r",stdin);
freopen(FROP".out","w",stdout);
sieve(100);
for(int i = 1;i <= n; i++)
if(!vis[i])printf("%d,",i);
return 0;
}
单数欧拉函数
int euler_phi(int n)
{
int ans=n;
int m= sqrt(n+0.5);
for(int i = 2; i <= m; 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;
}
求1-n的欧拉函数
O(nloglogn)
int phi[100];
void euler_table(int n)
{
for(int i = 2; i <= n; i++)phi[i]=0;
phi[1]=1;
for(int i = 2; i <= n;i++)if(!phi[i])
for(int j= i; j <= n; j+=i)
{
if(!phi[j])phi[j]=j;
phi[j]=phi[j]/i*(i-1);
}
}
快速幂
int power(int a,int b)
{
if(!b)return 1;
if(b==1)return a;
int p=power(a,b/2);
p=(LL)p*p%mod;
if(b%2)return p*a%mod;
return p;
}
差不多了,还有些以后再说吧。。。