数学做题记录
P3811 【模板】乘法逆元
数据范围是只能 \(\mathcal{O}(n)\) 过的。
考虑递推逆元。
设 \(t = p / i, k = p % i\)。
\(t * i + k \equiv 0(\bmod p)\).
\(k \equiv - t * i (\bmod p)\)
\(inv[i] \equiv - t * inv[k] (\bmod p)\)
\(inv[i] \equiv - p / i * inv[p % i] (\bmod p)\)。
注意可能出现负数,所以加上个 \(p\)。
/**
* author: TLE_Automation
* creater: 2022.8.22
* say: xpp 什么时候找到 npy 捏
**/
#include<cmath>
#include<queue>
#include<cstdio>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define gc getchar
#define INF 0x3f3f3f3f
#define int long long
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const int MAXN = 2e3 + 10;
const int Maxn = 2e5 + 10;
const int mod = 998244353;
const ll inf = 0x3f3f3f3f3f3f3f3f;
inline int gcd(int a, int b) {return !b ? a : gcd(b, a % b);}
inline void print(int x) {if (x < 0) putchar('-'), x = -x; if(x > 9) print(x / 10); putchar(x % 10 + '0');}
inline int ksm(int a, int b) {int base = a % mod, res = 1; while(b){if(b & 1) res = (res * base) % mod; base = (base * base) % mod, b >>= 1;}return res % mod;}
inline int mul(int a, int b) {int base = a % mod, res = 0; while(b){if(b & 1) res = (res + base) % mod; base = (base + base) % mod, b >>= 1;}return res % mod;}
inline char readchar() {static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;}
inline int read() { int res = 0, f = 0; char ch = gc();for (; !isdigit(ch); ch = gc()) f |= (ch == '-'); for (; isdigit(ch); ch = gc()) res = (res << 1) + (res << 3) + (ch ^ '0'); return f ? -res : res;}
ll inv[N << 2], n, p;
/*
t = p / i, k = p % i
t * i + k % p = 0
k \equiv -t * i (mod p)
inv[i] \equiv -t * inv[k] (mod p)
inv[i] \equiv - (p / i) * inv[p % i] (mod p)
inv[i] \equiv p - (p / i) * inv[p % i] (mod p)
*/
signed main()
{
n = read(), p = read();
inv[1] = 1;
for(int i = 2; i <= n; i++) inv[i] = ((p - (p / i) * inv[p % i]) % p + p) % p;
for(int i = 1; i <= n; i++) printf("%lld\n", inv[i]);
return (0 - 0);
}
P1349 广义斐波那契数列
简单矩乘。
直接推就行了。
/**
* author: TLE_Automation
* creater: 2022.8.23
**/
#include<cmath>
#include<queue>
#include<cstdio>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define gc getchar
#define INF 0x3f3f3f3f
#define int long long
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const int mod = 998244353;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define debug cout << "i ak ioi" << "\n"
inline void print(int x) {if (x < 0) putchar('-'), x = -x; if(x > 9) print(x / 10); putchar(x % 10 + '0');}
inline char readchar() {static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;}
inline int read() { int res = 0, f = 0; char ch = gc();for (; !isdigit(ch); ch = gc()) f |= (ch == '-'); for (; isdigit(ch); ch = gc()) res = (res << 1) + (res << 3) + (ch ^ '0'); return f ? -res : res;}
int p, q, a1, a2, n, m;
struct Mariax {
int a[5][5];
Mariax() {memset(a, 0, sizeof a);}
friend Mariax operator * (Mariax x, Mariax y) {
Mariax res;
for(int i = 1; i <= 2; i++)
for(int j = 1; j <= 2; j++)
for(int k = 1; k <= 2; k++)
res.a[i][j] = (res.a[i][j] + (x.a[i][k] * y.a[k][j]) % m) % m;
return res;
}
}Base, A;
Mariax ksm(Mariax B, int k) {
Mariax res;
for(int i = 1; i <= 2; i++) res.a[i][i] = 1;
while(k) {
if(k & 1) res = (res * B);
B = (B * B), k >>= 1;
}
return res;
}
signed main()
{
p = read(), q = read(), a1 = read(), a2 = read(), n = read(), m = read();
A.a[1][1] = a2, A.a[1][2] = a1;
Base.a[1][1] = p, Base.a[1][2] = 1, Base.a[2][1] = q, Base.a[2][2] = 0;
if(n == 1) return printf("%lld\n", a1 % m), 0;
else if(n == 2) return printf("%lld\n", a2 % m), 0;
A = A * ksm(Base, n - 1);
printf("%lld\n", A.a[1][2] % m);
return (0 - 0);
}
/**
* _ooOoo_
* o8888888o
* 88" . "88
* (| -_- |)
* O\ = /O
* ___/`---'\____
* . ' \\| |// `.
* / \\||| : |||// \
* / _||||| -:- |||||- \
* | | \\\ - /// | |
* | \_| ''\---/'' | |
* \ .-\__ `-` ___/-. /
* ___`. .' /--.--\ `. . __
* ."" '< `.___\_<|>_/___.' >'"".
* | | : `- \`.;`\ _ /`;.`/ - ` : | |
* \ \ `-. \_ __\ /__ _/ .-` / /
* ======`-.____`-.___\_____/___.-`____.-'======
* `=---='
* .............................................
* 佛曰:bug泛滥,我已瘫痪!
*/
P2421 [NOI2002] 荒岛野人
\(C_i + x P_i \equiv C_j + x P_j (\bmod M)\)。
\(x (P_i - P_j) \equiv C_j - C_i (\bmod M)\)。
\(x (P_i - P_j) = c_j - C_i + My\)。
\(x(P_i - P_j) - My = C_j - C_i\)
这个式子形如 \(ax + by = c\),可以用 exgcd 求解,发现 \(n \le 15, M \le 1e6\)。
考虑枚举 \(M\),exgcd 判断是否有解,如果有解的判断该解是否可行,指的是如果有解但是这俩个人相遇之前有一个人噶了。
/**
* author: TLE_Automation
* creater: 2022.8.22
* say: xpp 什么时候找到 npy 捏
**/
#include<cmath>
#include<queue>
#include<cstdio>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define gc getchar
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const int MAXN = 2e3 + 10;
const int Maxn = 2e5 + 10;
const int mod = 998244353;
const ll inf = 0x3f3f3f3f3f3f3f3f;
inline int gcd(int a, int b) {return !b ? a : gcd(b, a % b);}
inline void print(int x) {if (x < 0) putchar('-'), x = -x; if(x > 9) print(x / 10); putchar(x % 10 + '0');}
inline int ksm(int a, int b) {int base = a % mod, res = 1; while(b){if(b & 1) res = (res * base) % mod; base = (base * base) % mod, b >>= 1;}return res % mod;}
inline int mul(int a, int b) {int base = a % mod, res = 0; while(b){if(b & 1) res = (res + base) % mod; base = (base + base) % mod, b >>= 1;}return res % mod;}
inline char readchar() {static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;}
inline int read() { int res = 0, f = 0; char ch = gc();for (; !isdigit(ch); ch = gc()) f |= (ch == '-'); for (; isdigit(ch); ch = gc()) res = (res << 1) + (res << 3) + (ch ^ '0'); return f ? -res : res;}
int n, p[20], c[20], l[20];
int x, y, Max;
int exgcd(int a, int b, int &x, int &y) {
if(!b) {x = 1, y = 0; return a;}
int res = exgcd(b, a % b, x, y);
int tmp = x; x = y, y = tmp - (a / b) * y;
return res;
}
bool Check(int M) {
for(int i = 1; i <= n; i++) {
for(int j = i + 1; j <= n; j++) {
int a = p[i] - p[j], b = M, C = c[j] - c[i];
int Gcd = exgcd(a, b, x, y);
if(C % Gcd) continue;
a /= Gcd, b /= Gcd, C /= Gcd; b = abs(b);
x = (x * C % b + b) % b;
if(x <= l[i] && x <= l[j]) return false;
}
}
return 1;
}
signed main()
{
n = read();
for(int i = 1; i <= n; i++)
c[i] = read(), p[i] = read(), l[i] = read(), Max = std::max(Max, c[i]);
for(int i = Max; ; i++) if(Check(i)) return printf("%d\n", i), 0;
return (0 - 0);
}
P3868 [TJOI2009] 猜数字
\(b_i \mid (n - a_i)\)
\(n - a_i \equiv 0 (\bmod b_i)\)
\(n \equiv a_i (\bmod b_i)\)
然后就是 CRT 的板子了。
/**
* author: TLE_Automation
* creater: 2022.8.24
**/
#include<cmath>
#include<queue>
#include<cstdio>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define gc getchar
#define INF 0x3f3f3f3f
#define int long long
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const int mod = 998244353;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define debug cout << "i ak ioi" << "\n"
inline void print(int x) {if (x < 0) putchar('-'), x = -x; if(x > 9) print(x / 10); putchar(x % 10 + '0');}
inline char readchar() {static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;}
inline int read() { int res = 0, f = 0; char ch = gc();for (; !isdigit(ch); ch = gc()) f |= (ch == '-'); for (; isdigit(ch); ch = gc()) res = (res << 1) + (res << 3) + (ch ^ '0'); return f ? -res : res;}
int n, a[N], b[N], M = 1, x, y, ans = 0;
int exgcd(int a, int b, int &x, int &y) {
if(!b) {x = 1, y = 1; return a; }
int res = exgcd(b, a % b, x, y);
int tmp = x; x = y, y = tmp - (a / b) * y;
return res;
}
inline int mul(int a, int b, int p) {
int res = 0;
while(b) {
if(b & 1) res = (res + a) % p;
a = (a + a) % p, b >>= 1;
} return res;
}
signed main()
{
n = read();
for(int i = 1; i <= n; i++) a[i] = read();
for(int i = 1; i <= n; i++) b[i] = read(), M *= b[i];
for(int i = 1; i <= n; i++) a[i] = (a[i] + b[i]) % b[i];
for(int i = 1; i <= n; i++) {
int M_i = M / b[i];
exgcd(M_i, b[i], x, y);
x = (x + b[i]) % b[i];
ans = (ans + (mul(mul(M_i, x, M), a[i], M) + M) % M + M) % M;
}
printf("%lld\n", ans);
return (0 - 0);
}
/**
* _ooOoo_
* o8888888o
* 88" . "88
* (| -_- |)
* O\ = /O
* ___/`---'\____
* . ' \\| |// `.
* / \\||| : |||// \
* / _||||| -:- |||||- \
* | | \\\ - /// | |
* | \_| ''\---/'' | |
* \ .-\__ `-` ___/-. /
* ___`. .' /--.--\ `. . __
* ."" '< `.___\_<|>_/___.' >'"".
* | | : `- \`.;`\ _ /`;.`/ - ` : | |
* \ \ `-. \_ __\ /__ _/ .-` / /
* ======`-.____`-.___\_____/___.-`____.-'======
* `=---='
* .............................................
* 佛曰:bug泛滥,我已瘫痪!
*/