模板大全

barrett

点击查看代码
__int128 mu = -1ull / mod;
inline ll reduce(ll x) {
	ll r = x - (mu * x >> 64) * mod;
	return r >= mod ? r - mod : r;
}

O(n)-O(1) rmq

点击查看代码
namespace RMQ {
	const int N = 1e5 + 5;
	const int K = log2(N);
	const int M = N / K + 2;
	int al, a[N], lg[N], tt[N], lmx[N], rmx[N], pos[N], L[M], R[M], mx[M][21], st[N], stk[K];
	int query(int l, int r) {
		int p = pos[l], q = pos[r];
		if (p == q) return a[tt[st[r] >> (l - L[p])] + l];
		if (p == q - 1) return max(rmx[l], lmx[r]);
		p++, q--; int k = lg[q - p + 1];
		return max(max(mx[p][k], mx[q - (1 << k) + 1][k]), max(rmx[l], lmx[r]));
	}
	void init(int n) {
		for (int i = 2; i <= n; i++) lg[i] = lg[i >> 1] + 1;
		for (int i = 1; i <= n; i++) tt[i] = lg[i & -i];
		for (int i = 1; ; i++) {
			L[i] = R[i - 1] + 1, R[i] = min(n, R[i - 1] + lg[n]);
			lmx[L[i]] = a[L[i]], rmx[R[i]] = a[R[i]];
			for (int j = L[i] + 1; j <= R[i]; j++) lmx[j] = max(lmx[j - 1], a[j]);
			for (int j = R[i] - 1; j >= L[i]; j--) rmx[j] = max(rmx[j + 1], a[j]);
			for (int j = L[i], top = 0; j <= R[i]; j++) {
				st[j] = j - L[i] ? st[j - 1] : 0;
				while (top && a[j] > a[L[i] + stk[top]]) st[j] -= 1 << stk[top--];
				st[j] += 1 << (stk[++top] = j - L[i]), pos[j] = i;
			}
			mx[i][0] = lmx[R[i]]; if (R[i] == n) break;
		}
		for (int j = 1; j <= lg[pos[n]]; j++) {
			for (int i = 1; i + (1 << j) - 1 <= pos[n]; i++) {
				mx[i][j] = max(mx[i][j - 1], mx[i + (1 << (j - 1))][j - 1]);
			}
		}
	}
}

整式递推

点击查看代码
vector<vector<int>> find_rel(const vector<int> &a, int deg) {
	int n = a.size(), B = (n + 2) / (deg + 2), C = B * (deg + 1), R = n - (B - 1), c = 0;
	assert(B >= 2 && R >= C - 1);
	vector<vector<int>> b(R, vector<int>(C));
	for (int i = 0; i < R; i++) {
		for (int j = 0; j < B; j++) {
			for (int k = 0, x = a[i + j]; k <= deg; k++, x = (ll)x * (i + j) % mod) {
				b[i][j * (deg + 1) + k] = x;
			}
		}
	}
	for (c = 0; c < C; c++) {
		int p = -1;
		for (int i = c; i < R; i++) {
			if (b[i][c]) {
				p = i;
				break;
			}
		}
		if (p == -1) break;
		swap(b[p], b[c]);
		int w = qpow(b[c][c]);
		for (int i = c; i < C; i++) {
			b[c][i] = (ll)b[c][i] * w % mod;
		}
		for (int i = c + 1; i < R; i++) if (b[i][c]) {
			int t = b[i][c];
			for (int j = c; j < C; j++) {
				b[i][j] = (b[i][j] + mod - (ll)b[c][j] * t % mod) % mod;
			}
		}
	}
	assert(c != C);
	for (int i = c - 1; ~i; i--) if (b[i][c]) {
		for (int j = i - 1; ~j; j--) {
			b[j][c] = (b[j][c] + mod - (ll)b[i][c] * b[j][i] % mod) % mod;
		}
	}
	int od = c / (deg + 1);
	vector<vector<int>> ret(od + 1, vector<int>(deg + 1));
	ret[0][c % (deg + 1)] = 1;
	for (int i = c - 1; ~i; i--) {
		ret[od - i / (deg + 1)][i % (deg + 1)] = mod - b[i][c];
	}
	for (int i = 0; i <= od; i++) {
		vector<int> tmp(deg + 1);
		for (int k = 0; k <= deg; k++) {
			for (int j = k, s = 1; j <= deg; j++) {
				tmp[k] = (tmp[k] + (ll)s * ret[i][j]) % mod;
				s = (ll)s * (mod - i) % mod * (j + 1) % mod * qpow(j + 1 - k) % mod;
			}
		}
		ret[i] = tmp;
	}
	return ret;
}
posted @ 2023-01-27 19:57  后藤一里  阅读(60)  评论(0)    收藏  举报