文章目录
扩展欧几里得
ll exgcd(ll a,ll b,ll &x,ll &y)
{
if (!b)
{
x = 1,y = 0;
return a;
}
int r = exgcd(b,a%b,x,y);
int tmp = y;
y = x - (a / b) * y;
x = tmp;
return r;
}
矩阵快速幂 (O(x3nlogn)x为构造矩阵阶数)
以hduoj6470为例, f n = f n − 1 + 2 f n − 2 + n 3 fn = f_{n-1} + 2f_{n-2} + n^3 fn=fn−1+2fn−2+n3
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod = 123456789;
const int N = 6;
struct Matrix
{
int n;
ll d[6][6];
void init(int n)
{
this -> n = n;
memset(d,0,sizeof(d));
}
Matrix operator *(Matrix &b)
{
Matrix ans;
ans.init(n);
for (int i = 0;i < n;i ++)
for (int j = 0;j < n;j ++)
for (int k = 0;k < n;k ++)
ans.d[i][j]=(ans.d[i][j]+d[i][k]*b.d[k][j])%mod;
return ans;
}
};
ll a[N][N] = {
{
1,1,0,0,0,0},
{
2,0,0,0,0,0},
{
1,0,1,0,0,0},
{
3,0,3,1,0,0},
{
3,0,3,2,1,0},
{
1,0,1,1,1,1}
};
ll b[6] = {
2,1,8,4,2,1};
Matrix quick(Matrix a,ll b)
{
Matrix res;
res.init(a.n);
for (int i = 0;i < res.n;i ++)
res.d[i][i] = 1;
while (b)
{
if (b & 1) res = res * a;
a = a * a;
b >>= 1;
}
return res;
}
int main()
{
ll t,n;
scanf("%lld",&t);
while (t --)
{
scanf("%lld",&n);
if (n < 2)
{
printf("%lld\n",n);
continue;
}
Matrix x,ans;
x.init(6),ans.init(6);
for (int i = 0;i < N;i ++)
for (int j = 0;j < N;j ++)
x.d[i][j] = a[i][j];
for (int i = 0;i<N;i++) ans.d[0][i]=b[i];
x = quick(x,n - 1);
ans = ans * x;
printf("%lld\n",ans.d[0][1]);
}
return 0;
}
米勒罗宾素数检测
ll ksc(ll a,ll b,ll p)
{
return (a*b-(ll)((long double)a/p*b)*p+p)%p;
}
ll prime[5] = {
2, 5, 3, 233, 331};
ll qpow(ll a,ll b,ll p)
{
ll ans = 1;
while (b)
{
if (b & 1) ans = ksc(ans,a,p);
b >>= 1;
a = ksc(a,a,p);
}
return ans;
}
bool Miller_Rabin(ll p)
{
if(p < 2) return 0;
if(p != 2 && p % 2 == 0) return 0;
ll s = p - 1;
while(! (s & 1)) s >>= 1;
for(int i = 0; i < 3; ++i)
{
if(p == prime[i]) return 1;
ll t = s, m = qpow(prime[i], s, p);
while(t != p - 1 && m != 1 && m != p - 1)
{
m = ksc(m, m, p);
t <<= 1;
}
if(m != p - 1 && !(t & 1)) return 0;
}
return 1;
}
__int128
读入输出
inline __int128 read()
{
int X=0