快速幂:
ll qpow(ll a,ll b,ll p){
ll ans=1;
while(b){
if(b&1) ans=(ans*a)%p;
b>>=1;
a=(a*a)%p;
}
return ans;
}
millar-rabin:
在代码实现上,为了常数优化,所以选择倒着进行操作
const int P[15]={2,3,5,7,9,11,13,17,19};
bool mr(int x) {
rop(i,0,9) if(x==P[i]) return 1;
int u=x-1,t=0;
while(u%2==0){
u>>=1;
++t;
}
rop(i,0,9){
int a=P[i];
int v=qpow(a,u,x);
if(v==1) continue;
int s;
for(s=0;s<t;++s){
if(v==x-1) break;
v=(ll)v*v%x;
}
if(s==t) return 0;
}
return 1;
}
exgcd:
ll exgcd(ll a,ll b,ll &x,ll &y){
if(!b){
x=1;
y=0;
return a;
}
ans=exgcd(b,a%b,x,y);
ll t=x;
x=y;
y=t-a/b*y;
return ans;
}
gcd:
int gcd(int a,int b){
if(b==0) return a;
else return gcd(b,a%b);
}
int gcd(int a,int b){
if(a==b) return a;
if(!(a&1)&&!(b&1)) return 2*gcd(a>>1,b>>1);
else if((a&1)&&(b&1)){
if(a>b) return gcd(b,a-b);
else return gcd(a,b-a);
}
else {
if(a%2) return gcd(a,b>>1);
else return gcd(a>>1,b);
}
}
1~n的逆元
int getny(ll x){
return qpow(x,fp,p);
}
int main(){
n=iread();
p=iread();
FOR(i,1,n){
c[i]=(c[i-1]*1ll*i)%p;
}
inv[n]=getny(c[n]);
RFOR(i,n-1,1){
inv[i]=(inv[i+1]*1ll*(i+1))%p;
}
FOR(j,1,n){
printf("%d\n",inv[j]*1ll*c[j-1]%p);
}
return 0;
}
线性筛:
void init(ll n){
bj[1]=1;
FOR(i,2,n){
if(bj[i]==0){
pm[++tot]=i;
}
for(int j=1;j<=tot&&pm[j]*i<=n;++j){
bj[pm[j]*i]=1;
if(!(i%pm[j])) break;
}
}
}
线性筛求欧拉函数:
void init(ll n){
bj[1]=1;
FOR(i,2,n){
if(bj[i]==0){
pm[++tot]=i;
phi[i]=i-1;
}
for(int j=1;j<=tot&&pm[j]*i<=n;++j){
bj[pm[j]*i]=1;
if(!(i%pm[j])){
phi[i*pm[j]]=phi[i]*pm[j];
break;
}
else {
phi[i*pm[j]]=phi[i]*phi[pm[j]];
}
}
}
}
线性筛约数个数
void init(ll n){
bj[1]=1;
FOR(i,2,n){
if(bj[i]==0){
pm[++tot]=i;
phi[i]=i-1;
}
for(int j=1;j<=tot&&pm[j]*i<=n;++j){
bj[pm[j]*i]=1;
if(!(i%pm[j])){
phi[i*pm[j]]=phi[i]*pm[j];
break;
}
else {
phi[i*pm[j]]=phi[i]*phi[pm[j]];
}
}
}
}
1~n!分解质因数:
#include<cstdio>
#include<string>
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
int iread(){char c;int x=0,y=1;c=getchar();while(c<'0'||c>'9'){if(c=='-') y=-1;c=getchar();}while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^'0');c=getchar();}return x*y;}
int n;
const int N=1e6+5;
bool vis[N];
int cnt[N];
int p[N],tot;
void pre(int n){
FOR(i,2,n){
if(!vis[i]){
p[++tot]=i;
}
FOR(j,1,tot){
int pri_j=p[j];
if(i*pri_j>n) break;
vis[i*pri_j]=1;
if(i%pri_j==0){
break;
}
}
}
}
int qmax(int a,int b){
return (a>b ? a : b);
}
int dmax=0;
void work(int x){
int jx=x;
FOR(i,1,tot){
int pri=p[i];
if(pri*pri>jx||pri>x) break;
while(x%pri==0){
++cnt[pri];
x/=pri;
dmax=qmax(dmax,pri);
}
}
if(x){
++cnt[x];
dmax=qmax(dmax,x);
}
}
int main(){
n=iread();
pre(n);
FOR(i,1,n) work(i);
FOR(j,1,tot){
int i=p[j];
if(i>dmax) break;
if(cnt[i]) printf("%d %d\n",i,cnt[i]);
}
return 0;
}
int n;
const int N=1e6+5;
int cnt[N];
int cnt_[N];
int p[N],tot,top;
int vis[N];
void dfs(int x){
FOR(j,1,tot){
if(x*p[j]>n) return ;
else {
cnt_[++top]=p[j];
if(!vis[x*p[j]]){
FOR(l,1,top){
++cnt[cnt_[l]];
}
}
vis[x*p[j]]=1;
dfs(x*p[j]);
--top;
}
}
}
int main(){
n=iread();
FOR(i,2,n){
if(!vis[i]){
p[++tot]=i;
++cnt[i];
cnt_[++top]=i;
dfs(i);
top=0;
}
}
FOR(i,2,n){
if(cnt[i]){
printf("%d %d\n",i,cnt[i]);
}
}
return 0;
}
excrt:
ll exgcd(ll a,ll b,ll &x,ll &y,ll c){
if(!b){
x=c/a;
y=0;
return a;
}
ll g=exgcd(b,a%b,y,x,c);
y-=a/b*x;
x=x%(b/g);
y=(c-a*x)/b;
return g;
}
ll gsc(ll a,ll b,ll p){
ll ans=0;
while(b){
if(b&1) ans=(ans+a)%p;
b>>=1;
a=(a+a)%p;
}
return ans;
}
int n;
void excrt(ll &A,ll &P,ll a,ll p) {
ll x=0,y=0;
ll g=exgcd(p,-P,x,y,A-a);
g=(g<0 ? -g : g);
P=p/g*P;
A=a+gsc(x,p,P);
A=(A%P+P)%P;
}
ll A,P,a,p;
int main(){
n=iread();
scanf("%lld%lld",&P,&A);
FOR(i,2,n) {
scanf("%lld%lld",&p,&a);
excrt(A,P,a,p);
}
cout<<(long long)((A%P+P)%P);
return 0;
}
卡特兰数:
ll qpow(ll a,ll b,ll p){
ll ans=1;
while(b){
if(b&1) ans=(ans*a)%p;
b>>=1;
a=(a*a)%p;
}
return ans;
}
const int N=2e5+5;
const int mod=1e9+7;
ll f[N],c[N]={1},ans;
void init(){
FOR(i,1,N-3) c[i]=c[i-1]*i%mod;
}
ll C(int n,int m){
return c[n]*qpow(c[m],mod-2,mod)%mod*qpow(c[n-m],mod-2,mod)%mod;
}
int n;
int main(){
n=iread();
init();
cout<<C(2*n,n)*qpow(n+1,mod-2,mod)%mod;
return 0;
}
bsgs:
ll bsgs(ll a,ll b,ll p){
map<ll,ll> hs;
hs.clear();
b%=p;
ll t=sqrt(p)+1;
rop(i,0,t){
hs[b*qpow(a,i,p)%p]=i;
}
a=qpow(a,t,p);
if(!a) return (!b ? 1 : -1);
FOR(i,1,t){
ll val=qpow(a,i,p);
ll j=(hs.find(val)==hs.end() ? -1 : hs[val]);
if(j>=0&&i*t-j>=0) return i*t-j;
}
return -1;
}
省事的求组合数:
ll c[N]={1};
void init(){
FOR(i,1,N-5) c[i]=c[i-1]*i%mod;
}
ll C(int n,int m){
if(m>n||n<0||m<0) return 0;
return c[n]*qpow(c[m],mod-2,mod)%mod*qpow(c[n-m],mod-2,mod)%mod;
}