qwq以下都为9.24后写的模板
快读
inline int read() {
int x = 0, k = 1; char c = getchar();
for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
return k ? x : -x;
}
快速幂
inline int ksm(int a, int b) {
int ans = 1;
for (; b; b >>= 1, a = 1LL * a * a % Mo)
if (b & 1) ans = 1LL * ans * a % Mo;
return ans;
}
扩欧
void exgcd(int a, int b) {
if (b == 0) {
x = 1, y = 0;
return;
}
exgcd(b, a % b);
int k = x;
x = y, y = k - a / b * y;
}
后缀自动机(PAM) (9.24)
#include<bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
char s[N];
int Len;
struct PAM{
int last, cnt, len[N], fail[N], num[N], k, p, ch[N][26], p1, c[N];
//char s[N];
void init(char *s) {
last = 0, cnt = 1, len[0] = 0, len[1] = -1, fail[0] = 1, fail[1] = 0, s[0] = 26;
}
void insert() {
for (int i = 1; i <= Len; i++) {
s[i] = (s[i] - 97 + k) % 26 + 97;
c[i] = s[i] - 'a';
p = last;
while (s[i - len[p] - 1] != s[i])
p = fail[p];
if (!ch[p][s[i]]) {
len[++cnt] = len[p] + 2, p1 = fail[p];
while (s[i - len[p1] - 1] != s[i])
p1 = fail[p1];
fail[cnt] = ch[p1][s[i]];
num[cnt] = num[fail[cnt]] + 1;
ch[p][s[i]] = cnt;
}
last = ch[p][s[i]];
printf("%d%c", num[last], (i == Len) ? '\n' : ' ');
k = num[last];
}
}
} s1;
int main() {
scanf("%s", s + 1);
Len = strlen(s + 1);
s1.init(s);
s1.insert();
return 0;
}
AC自动机 (9.25)
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10, M = 160;
int n;
char s[M][N];
int trie[N][26], tot, endword[N], fail[N];
struct Node {
int num, pos;
} Ans[N];
inline void Init(int x) {
memset(trie[x], 0, sizeof(trie[x]));
fail[x] = endword[x] = 0;
}
inline void Build_Trie(int gg) {
int root = 0, len = strlen(s[gg] + 1);
for (int j = 1; j <= len; j++) {
if (!trie[root][s[gg][j] - 'a'])
trie[root][s[gg][j] - 'a'] = ++tot, Init(tot);
root = trie[root][s[gg][j] - 'a'];
}
endword[root] = gg;
}
inline void Get_Fail() {
queue <int> q;
for (int i = 0; i < 26; i++)
if (trie[0][i]) {
q.push(trie[0][i]);
fail[trie[0][i]] = 0;
}
while (!q.empty()) {
int now = q.front();
q.pop();
for (int i = 0; i < 26; i++)
if (trie[now][i]) {
fail[trie[now][i]] = trie[fail[now]][i];
q.push(trie[now][i]);
}
else {
trie[now][i] = trie[fail[now]][i];
}
}
}
inline int query() {
int len = strlen(s[n + 1] + 1), ans = 0, now = 0;
for (int i = 1; i <= len; i++) {
now = trie[now][s[n + 1][i] - 'a'];
for (int j = now; j; j = fail[j])
Ans[endword[j]].num++;
}
return ans;
}
inline bool cmp(Node x, Node y) {
return x.num > y.num || (x.num == y.num && x.pos < y.pos);
}
int main() {
scanf("%d", &n);
while (n != 0) {
tot = 0;
Init(0);
for (int i = 1; i <= n; i++) {
scanf("%s", s[i] + 1);
Ans[i].num = 0, Ans[i].pos = i;
Build_Trie(i);
}
fail[0] = 0;
Get_Fail();
scanf("%s", s[n + 1] + 1);
query();
std::sort(Ans + 1, Ans + 1 + n, cmp);
printf("%d\n%s\n", Ans[1].num, s[Ans[1].pos] + 1);
for (int i = 2; i <= n; i++)
if (Ans[1].num == Ans[i].num)
printf("%s\n", s[Ans[i].pos] + 1);
else
break;
scanf("%d", &n);
}
return 0;
}
可持久化线段树(主席树) (9.25)
(静态区间第k小)
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int l[N << 5], r[N << 5], cnt, sum[N << 5], a[N], b[N], c[N], n, q, m;
inline int read() {
int x = 0, k = 1; char c = getchar();
for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
return k ? x : -x;
}
inline int Build(int t, int w) {
int now = ++cnt, mid = (t + w) >> 1;
sum[now] = 0;
if (t < w) {
l[now] = Build(t, mid);
r[now] = Build(mid + 1, w);
}
return now;
}
inline int add(int k, int t, int w, int x) {
int now = ++cnt, mid = (t + w) >> 1;
l[now] = l[k], r[now] = r[k], sum[now] = sum[k] + 1;
if (t < w && x <= mid)
l[now] = add(l[k], t, mid, x);
else if (t < w && x > mid)
r[now] = add(r[k], mid + 1, w, x);
return now;
}
inline int ask(int L, int R, int t, int w, int x) {
if (t >= w)
return t;
int mid = (t + w) >> 1, k = sum[l[R]] - sum[l[L]];
if (k >= x)
return ask(l[L], l[R], t, mid, x);
else
return ask(r[L], r[R], mid + 1, w, x - k);
}
int main() {
n = read(), q = read();
for (int i = 1; i <= n; i++)
b[i] = a[i] = read();
std::sort(b + 1, b + 1 + n);
m = unique(b + 1, b + 1 + n) - b - 1;
c[0] = Build(1, m);
for (int i = 1; i <= n; i++) {
int now = lower_bound(b + 1, b + 1 + m, a[i]) - b;
c[i] = add(c[i - 1], 1, m, now);
}
for (int i = 1; i <= q; i++) {
int x = read(), y = read(), z = read();
printf("%d\n", b[ask(c[x - 1], c[y], 1, m, z)]);
}
return 0;
}
Manacher (9.25)
#include<bits/stdc++.h>
using namespace std;
const int N = 31000000;
int len, hw[N], ans;
char s[N];
inline void Manacher() {
int maxright = 0, mid = 0;
for (int i = 1; i < len; i++) {
if (i < maxright)
hw[i] = std::min(hw[(mid << 1) - i], hw[mid] + mid - i);
else
hw[i] = 1;
while (s[i + hw[i]] == s[i - hw[i]])
++hw[i];
if (hw[i] + i > maxright)
maxright = hw[i] + i, mid = i;
}
}
int main() {
scanf("%s", s + 1);
len = strlen(s + 1);
for (int i = len; i >= 1; i--)
s[i * 2] = s[i];
s[0] = s[1] = '#';
for (int i = 1; i <= len; i++)
s[i * 2 + 1] = '#';
s[len * 2 + 2] = 0;
len = len * 2 + 2;
Manacher();
ans = 1;
for (int i = 0; i < len; i++)
ans = std::max(ans, hw[i]);
printf("%d\n", ans - 1);
return 0;
}
线性基 (9.26)
插入、判断、查询最大最小值、查询第\(k\)小值
#include<bits/stdc++.h>
using namespace std;
const int M = 60;
int n;
long long x, a[M + 10], b[M +10];
bool flag;
inline int read() {
int x = 0, k = 1; char c = getchar();
for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
return k ? x : -x;
}
inline long long read1() {
long long x = 0, k = 1; char c = getchar();
for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
return k ? x : -x;
}
inline void Insert(long long x) { //插入
for (int i = M; i >= 0; i--)
if (x & (1ll << i))
if (!a[i]) {
a[i] = x;
return;
}
else x ^= a[i];
flag = true;
}
inline bool check(long long x) { //判断
for (int i = M; i >= 0; i--)
if (x & (1ll << i))
if (!a[i])
return false;
else
x ^= a[i];
return true;
}
inline long long Ask_max() { //查询最大值
long long maxx = 0;
for (int i = M; i >= 0; i--)
maxx = std::max(maxx, maxx ^ a[i]);
return maxx;
}
inline long long Ask_min() { //查询最小值
if (flag)
return 0;
for (int i = 0; i <= M; i++)
if (a[i])
return a[i];
}
inline long long Ask_kth(long long x) { //查询第k小值
long long ans = 0;
int cnt = 0;
x -= flag;
if (!x)
return 0;
for (int i = 0; i <= M; i++) {
for (int j = i - 1; j >= 0; j--)
if (a[i] & (1ll << j))
a[i] ^= a[j];
if (a[i])
b[++cnt] = a[i];
}
if (x >= (1ll << cnt))
return -1;
for (int i = 0; i < cnt; i++)
if (x & (1ll << i))
ans ^= b[i];
return ans;
}
int main() {
n = read();
for (int i = 1; i <= n; i++) {
x = read1();
Insert(x);
}
printf("%lld\n", Ask_max());
return 0;
}
高斯消元 (9.26)
#include<bits/stdc++.h>
using namespace std;
const int N = 110;
int n;
double a[N][N];
inline bool Gauss(int n, int m) {
for (int i = 1; i <= n; i++) {
int maxx = i;
for (int j = i + 1; j <= n; j++)
if (fabs(a[j][i]) > fabs(a[maxx][i]))
maxx = j;
for (int j = 1; j <= m; j++)
std::swap(a[i][j], a[maxx][j]);
if (!a[i][i])
return false;
for (int j = 1; j <= n; j++)
if (j != i) {
double t = a[j][i] / a[i][i];
for (int k = i + 1; k <= m; k++)
a[j][k] = a[j][k] - a[i][k] * t;
}
}
return true;
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n + 1; j++)
scanf("%lf", &a[i][j]);
if (!Gauss(n, n + 1))
return printf("No Solution\n"), 0;
for (int i = 1; i <= n; i++)
printf("%.2f\n", a[i][n + 1] / a[i][i]);
return 0;
}
矩阵求逆 (9.26)
#include<bits/stdc++.h>
using namespace std;
const int N = 1010, Mo = 1e9 + 7;
int n, a[N][N];
inline int ksm(int a, int b) {
int ans = 1;
for (; b; b >>= 1, a = 1LL * a * a % Mo)
if (b & 1) ans = 1LL * ans * a % Mo;
return ans;
}
inline bool Gauss(int n, int m) {
for (int i = 1; i <= n; i++) {
int maxx = i;
for (int j = i + 1; j <= n; j++)
if (fabs(a[j][i]) > fabs(a[maxx][i]))
maxx = j;
if (i != maxx)
for (int j = 1; j <= m; j++)
std::swap(a[i][j], a[maxx][j]);
if (!a[i][i])
return false;
int d = ksm(a[i][i], Mo - 2);
for (int j = i; j <= m; j++)
a[i][j] = 1LL * a[i][j] * d % Mo;
for (int j = 1; j <= n; j++)
if (j != i) {
d = a[j][i];
for (int k = i; k <= m; k++)
a[j][k] = (a[j][k] - 1LL * a[i][k] * d % Mo + Mo) % Mo;
}
}
return true;
}
signed main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++)
scanf("%d", &a[i][j]);
a[i][n + i] = 1;
}
if (!Gauss(n, n + n))
return printf("No Solution\n"), 0;
for (int i = 1; i <= n; i++)
for (int j = n + 1; j <= n + n; j++)
printf("%d%c", a[i][j], " \n"[j == n + n]);
return 0;
}
普通莫队 (9.27)
#include<bits/stdc++.h>
using namespace std;
const int N = 3e4 + 10, M = 2e6 + 10;
int n, m, now, be[M], a[M], cnt[M], ans[M];
struct Node {
int l, r, id;
} q[M];
inline int read() {
int x = 0, k = 1; char c = getchar();
for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
return k ? x : -x;
}
inline bool cmp(Node a, Node b) {
return (be[a.l] ^ be[b.l]) ? be[a.l] < be[b.l] : ((be[a.l] & 1) ? a.r < b.r : a.r > b.r);
}
int main() {
n = read();
int sz = sqrt(n), n1 = ceil((double)n / sz);
for (int i = 1; i <= n1; i++)
for (int j = (i - 1) * sz + 1; j <= i * sz; j++)
be[j] = i;
for (int i = 1; i <= n; i++)
a[i] = read();
m = read();
for (int i = 1; i <= m; i++)
q[i].l = read(), q[i].r = read(), q[i].id = i;
std::sort(q + 1, q + 1 + m, cmp);
int L = 1, R = 0;
for (int i = 1; i <= m; i++) {
int l = q[i].l, r = q[i].r;
while (L < l)
now -= !--cnt[a[L++]];
while (L > l)
now += !cnt[a[--L]]++;
while (R < r)
now += !cnt[a[++R]]++;
while (R > r)
now -= !--cnt[a[R--]];
ans[q[i].id] = now;
}
for (int i = 1; i <= m; i++)
printf("%d\n", ans[i]);
return 0;
}
带修莫队 (9.27)
#include<bits/stdc++.h>
using namespace std;
const int N = 3e4 + 10, M = 2e6 + 10;
int n, m, now, be[M], a[M], cnt[M], ans[M], cntc, cntq;
char ch;
struct Query {
int l, r, id, time;
} q[M];
struct Replace {
int pos, color;
} c[M];
inline int read() {
int x = 0, k = 1; char c = getchar();
for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
return k ? x : -x;
}
inline bool cmp(Query a, Query b) {
return (be[a.l] ^ be[b.l]) ? be[a.l] < be[b.l] : ((be[a.r] ^ be[b.r]) ? be[a.r] < be[b.r] : a.time < b.time);
}
int main() {
n = read(), m = read();
int sz = pow(n, 2.0 / 3.0), n1 = ceil((double)n / sz);
for (int i = 1; i <= n1; i++)
for (int j = (i - 1) * sz + 1; j <= i * sz; j++)
be[j] = i;
for (int i = 1; i <= n; i++)
a[i] = read();
for (int i = 1; i <= m; i++) {
scanf("%c", &ch);
while (ch != 'Q' && ch != 'R')
scanf("%c", &ch);
if (ch == 'Q') {
q[++cntq].l = read(), q[cntq].r = read(), q[cntq].time = cntc, q[cntq].id = cntq;
}
else if (ch == 'R') {
c[++cntc].pos = read(), c[cntc].color = read();
}
}
std::sort(q + 1, q + 1 + cntq, cmp);
int L = 1, R = 0, Time = 0;
for (int i = 1; i <= m; i++) {
int l = q[i].l, r = q[i].r, time = q[i].time;
while (L < l)
now -= !--cnt[a[L++]];
while (L > l)
now += !cnt[a[--L]]++;
while (R < r)
now += !cnt[a[++R]]++;
while (R > r)
now -= !--cnt[a[R--]];
while (Time < time) {
Time++;
if (l <= c[Time].pos && r >= c[Time].pos)
now -= !--cnt[a[c[Time].pos]] - !cnt[c[Time].color]++;
std::swap(a[c[Time].pos], c[Time].color);
}
while (Time > time) {
if (l <= c[Time].pos && r >= c[Time].pos)
now -= !--cnt[a[c[Time].pos]] - !cnt[c[Time].color]++;
std::swap(a[c[Time].pos], c[Time].color);
Time--;
}
ans[q[i].id] = now;
}
for (int i = 1; i <= cntq; i++)
printf("%d\n", ans[i]);
return 0;
}