intrandint(int a, int b) { uniform_int_distribution<int> dis(a, b); returndis(eng); }
intquickPow(int x, int n, int p) { int res = 1; while (n) { if (n & 1)res = (ll)res * x%p; x = (ll)x * x%p; n >>= 1; } return res; }
boolisPrime(int x) { if (x < 3)return x == 2; for (int i = 0; i < 12; i++) { int a = randint(2, x - 1); if (quickPow(a, x - 1, x) != 1) returnfalse; } returntrue; }
intmain() { if (isPrime(9997579))puts("YES"); elseputs("NO"); return0; }
boolisPrime(int x) { if (x < 3)return x == 2; for (int i = 0; i < 12; i++) { int a = randint(2, x - 1); if (quickPow(a, x - 1, x) != 1) returnfalse; } returntrue; }
米勒-拉宾素性检验
对于待检验的数为偶数,可直接判断其为非素数,而奇数则可写成 \(a^{x-1}\) 表示为 \(a^{2^rd}\) 当考虑 x 为奇数时,\(a^d,a^{2d},...,a^{2^rd}\)
这样一串数字的性质。
我们已经知道对奇素数 \(x\),\(a^{2^rd} \equiv 1 (mod\ x)\) (a 是 x
的倍数的情况下特判),也就是说这串数字以 1 结尾,由于 x 是奇素数,且
\(1^{\frac{x-1}{2}} \equiv 1 (mod\
x)\)
typedeflonglong ll; constint N = 1000010; int l, r; int prime[N], countNum; bool st[N];
voidinit(int n) { memset(st, 0, sizeof st); countNum = 0; for (int i = 2; i <= n; i++) { if (!st[i])prime[countNum++] = i; for (int j = 0; prime[j] * i <= n; i++) { st[prime[j] * i] = true; if (i % prime[j] == 0)break; } } }
intmain() { while (cin >> l >> r) { init(50000);
memset(st, 0, sizeof st); for (int i = 0; i < countNum; i++) { ll p = prime[i]; for (ll j = max(p * 2, (l + p - 1) / p * p); j <= r; j += p) st[j - l] = true; } countNum = 0; for (int i = 0; i <= r - l; i++) { if (!st[i] && i + l >= 2) prime[countNum++] = i + l; }
if (countNum < 2)puts("There are no adjacent primes."); else { int minp = 0, maxp = 0; for (int i = 0; i < countNum - 1; i++) { int d = prime[i + 1] - prime[i]; if (d < prime[minp + 1] - prime[minp])minp = i; if (d > prime[maxp + 1] - prime[maxp])maxp = i; } printf("%d,%d are closest, %d,%d are most distant.\n", prime[minp], prime[minp + 1], prime[maxp], prime[maxp + 1]); } } }
分解质因数
197
阶乘分解
最先开始想的是对于每一个 n
以内的数都枚举一下,记录其对各个质数的约数,但这样就会有 1e6*1e5(1e6
以内的素数个数)的时间复杂度,仍然超限,因此,转换一下思路,枚举素数,对每个该素数的倍数加入
s 值,即: \[
s = n/p + n/p^2 + n/p^3 + n/p^4...
\]
int qmi(int a, int k) { int res = 1; a %= mod; while (k) { if (k & 1) res = res * a % mod; a = a * a % mod; k >>= 1; } return res; }
int sum(int p, int k) { if (k == 1) return 1; if (k % 2 == 0) return (1 + qmi(p, k / 2)) * sum(p, k / 2) % mod; return (sum(p, k - 1) + qmi(p, k - 1)) % mod; }
int main() { int a, b; scanf("%d%d", &a, &b);
int ans = 1; for (int i = 2; i * i <= a; i ++ ) if (a % i == 0) { int s = 0; while (a % i == 0) { a /= i, s ++ ; } ans = ans * sum(i, b * s + 1) % mod; }
if (a > 1) ans = ans * sum(a, b + 1) % mod; if (a == 0) ans = 0;
int n; cin >> n; while (n -- ) { int a, b, c, d; cin >> a >> b >> c >> d;
fcnt = 0; int t = d; for (int i = 0; prime[i] <= t / prime[i]; i ++ ) { int p = prime[i]; if (t % p == 0) { int s = 0; while (t % p == 0) t /= p, s ++ ; factor[fcnt ++ ] = {p, s}; } }
if (t > 1) factor[fcnt ++ ] = {t, 1};
dcnt = 0; dfs(0, 1);
int res = 0; for (int i = 0; i < dcnt; i ++ ) { int x = dividor[i]; if (gcd(a, x) == b && (ll)c * x / gcd(c, x) == d) res ++ ; }
intmain() { cin>>n>>m; int F1[N][N]={1,1,1,0}; int A[N][N]={ {0,1,0,0}, {1,1,1,0}, {0,0,1,1}, {0,0,0,1} }; int k=n-1; while(k) { if(k&1)mul(F1,F1,A); mul(A,A,A); k>>=1; } cout<<(1ll*F1[0][2]*n-F1[0][3]+m)%m<<endl; return0; }
组合数学
这里给出一下一个非常常用的全排列函数:
next_permutation()
这个函数也十分便于记忆,permutation即排列的意思。
总结
I
利用 Cab = Ca-1b+Ca-1b-1 的组合数学规律 dp 出二位数组保存结果
II
利用除以一个数等于乘以一个数的逆元的形式预处理出阶乘,o1
的时间内得到特定结果
多重集合的全排列
多重集合的定义:多重集合不要求元素不能重复
多重集合表示:
M ={k1⋅a1, k2⋅a2, ⋯, kn⋅an}M ={k1⋅a1, k2⋅a2, ⋯, kn⋅an}(其中每个 ai
代表是不同的元素,每个元素 ai 有 ki 个,ki 可以是有限数,也可以是
∞。)(其中每个 ai 代表是不同的元素,每个元素 ai 有 ki 个,ki
可以是有限数,也可以是 ∞。)
多重集的排列:
多重集合 M ={k1⋅a1, k2⋅a2, ⋯, kn⋅an}的 r 排列数为 kr 多重集合 M
={k1⋅a1, k2⋅a2, ⋯, kn⋅an}的 r 排列数为 \(k^r\)
多重集合 M ={k1⋅a1, k2⋅a2, ⋯, kn⋅an}的全排列数为:\(\frac{(k1+k2+⋯+kn)!}{k1!k2!⋯kn!}\)
数学知识
排列
错排公式
错排问题
错排问题 考虑一个有 n
个元素的排列,若一个排列中所有的元素都不在自己原来的位置上,那么这样的排列就称为原排列的一个错排。
n 个元素的错排数记为
D(n)。研究一个排列错排个数的问题,叫做错排问题或称为更列问题。
错排公式的递推
对于 $D(n) $,考虑第 \(n\)
个位置,它可以与 \(n-1\)
前的任意位置交换 \(((n-1)D(n-1))\),在考虑编号为 k
的位置,这是有两种情况
#define int ll #define pb push_back #define endl '\n' #define x first #define y second #define Endl endl #define pre(i,a,b) for(int i=a;i<=b;i++) #define rep(i,b,a) for(int i=b;i>=a;i--) #define si(x) scanf("%d", &x); #define sl(x) scanf("%lld", &x); #define ss(x) scanf("%s", x); #define YES {puts("YES");return;} #define NO {puts("NO"); return;} #define all(x) x.begin(),x.end()
usingnamespace std;
typedeflonglong ll; typedefunsignedlonglong ull; typedef pair<int, int> PII; typedef pair<int, PII> PIII; typedef pair<char, int> PCI; typedef pair<int, char> PIC; typedef pair<double, double> PDD; typedef pair<ll, ll> PLL; constint N = 200010, M = 2 * N, B = N, MOD = 1000000007; constint INF = 0x3f3f3f3f; const ll LLINF = 0x3f3f3f3f3f3f3f3f;
int dx[4] = { -1,0,1,0 }, dy[4] = { 0,1,0,-1 }; int n, m, k; ll a[N], p[N], q[N];
ll gcd(ll a, ll b){ return b ? gcd(b, a % b) : a; } ll lowbit(ll x){ return x & -x; } ll qmi(ll a, ll b, ll mod){ ll res = 1; while (b) { if (b & 1) res = res * a % mod; a = a * a % mod; b >>= 1; } return res; }
inlinevoidinit(){}
voidinsert(ll x) { rep(i, 63, 0) { if (!(x >> i))continue; if (!p[i]) { p[i] = x; break; } x ^= p[i]; } }
#define int ll #define pb push_back #define endl '\n' #define x first #define y second #define Endl endl #define pre(i,a,b) for(int i=a;i<=b;i++) #define rep(i,b,a) for(int i=b;i>=a;i--) #define si(x) scanf("%d", &x); #define sl(x) scanf("%lld", &x); #define ss(x) scanf("%s", x); #define YES {puts("YES");return;} #define NO {puts("NO"); return;} #define all(x) x.begin(),x.end()
usingnamespace std;
typedeflonglong ll; typedefunsignedlonglong ull; typedef pair<int, int> PII; typedef pair<int, PII> PIII; typedef pair<char, int> PCI; typedef pair<int, char> PIC; typedef pair<double, double> PDD; typedef pair<ll, ll> PLL; constint N = 200010, M = 2 * N, B = N, MOD = 1000000007; constint INF = 0x3f3f3f3f; const ll LLINF = 0x3f3f3f3f3f3f3f3f;
int dx[4] = { -1,0,1,0 }, dy[4] = { 0,1,0,-1 }; int n, m, k; int h[N], ne[M], e[M], idx; ll w[M], p[N], verval[N]; ll ans;
ll gcd(ll a, ll b){ return b ? gcd(b, a % b) : a; } ll lowbit(ll x){ return x & -x; } ll qmi(ll a, ll b, ll mod){ ll res = 1; while (b) { if (b & 1) res = res * a % mod; a = a * a % mod; b >>= 1; } return res; }
inlinevoidinit(){}
voidadd(int a, int b, int c) { e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++; }
inlinevoidinsert(ll x) { rep(i, 63, 0) { if (!(x >> i & 1))continue; if (!p[i]) { p[i] = x; break; } x ^= p[i]; } }
voiddfs(int u, ll val) { verval[u] = val;
for (int i = h[u]; ~i; i = ne[i]) { int j = e[i]; if (verval[j] != -1) { insert(val ^ verval[j] ^ w[i]); continue; } dfs(j, val ^ w[i]); } return; }
voidslove() { memset(verval, -1, sizeof verval); memset(h, -1, sizeof h); cin >> n >> m; int a, b, c; pre(i, 1, m) { cin >> a >> b >> c; add(a, b, c); add(b, a, c); }
dfs(1, 0);
ll t = ans= verval[n]; rep(i, 63, 0) { ans = max(ans, ans ^ p[i]); } cout << ans << endl; }
signedmain() { int _; //si(_); _ = 1; init(); while (_--) { slove(); } return0; }
//#define int ll #define pb push_back #define endl '\n' #define x first #define y second #define Endl endl #define pre(i,a,b) for(int i=a;i<=b;i++) #define rep(i,b,a) for(int i=b;i>=a;i--) #define si(x) scanf("%d", &x); #define sl(x) scanf("%lld", &x); #define ss(x) scanf("%s", x); #define YES {puts("YES");return;} #define NO {puts("NO"); return;} #define all(x) x.begin(),x.end()
usingnamespace std;
typedeflonglong ll; typedefunsignedlonglong ull; typedef pair<int, int> PII; typedef pair<int, PII> PIII; typedef pair<char, int> PCI; typedef pair<int, char> PIC; typedef pair<double, double> PDD; typedef pair<ll, ll> PLL; constint N = 200010, M = 2 * N, B = N, MOD = 998244353; constint INF = 0x3f3f3f3f; const ll LLINF = 0x3f3f3f3f3f3f3f3f;
int dx[4] = { -1,0,1,0 }, dy[4] = { 0,1,0,-1 }; int n, m, k; int a[N], p[35];
ll gcd(ll a, ll b){ return b ? gcd(b, a % b) : a; } ll lowbit(ll x){ return x & -x; } ll qmi(ll a, ll b, ll mod){ ll res = 1; while (b) { if (b & 1) res = res * a % mod; a = a * a % mod; b >>= 1; } return res; }
inlinevoidinit(){}
boolinsert(int x){ bool res = false; rep(i, 30, 0) { if (((x >> i) & 1)==0)continue; if (p[i]==0) { p[i] = x; res = true; break; } x ^= p[i]; } return res; }
voidslove() { cin >> n; pre(i, 1, n)cin >> a[i];
int t=0; pre(i, 1, n) { insert(a[i]); t ^= a[i]; } if (!t) { cout << -1 << endl; return; } else { int cnt = 0; pre(i, 0, 30)if (p[i])cnt++; cout << cnt << Endl; } }
signedmain() { int _; //si(_); _ = 1; init(); while (_--) { slove(); } return0; }