qwq以下都为9.24后写的模板

namespace IO{
const int S = 1 << 20;
char I[S + 1], *Is = I, *It = I, O[S + 1], *Ot = O;
char gc() {return Is == It ? ((It = (Is = I) + fread(I, 1, S, stdin)) == I ? EOF: *Is++): *Is++;}
void flush() {fwrite(O, 1, Ot - O, stdout), Ot = O;}
void pc(char ch) {Ot == O + S? flush(), *Ot++ =ch: *Ot++ = ch;}
struct flusher{ ~flusher(){flush();}}Flusher;
#define getchar gc
#define putchar pc
inline int read() {
int x = 0; char v = gc();
for (; v < 48 || v > 57; v = gc());
for (; v >= 48 && v <= 57; v = gc()) x = (x << 3) + (x << 1) + (v ^ 48);
return x;
}
inline void write(int x) {
static int buf[100], d;
if (x == 0) pc('0');
else {
for (d = 0; x; x /= 10) buf[++d] = x % 10 + 48;
while (d) pc((char)buf[d--]);
}
}
}
using namespace IO;

快读

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;
}

GCD

int GCD(int x, int y) {
return y ? GCD(y, x % y) : 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;
}
int exgcd(int a, int b, int &x, int &y) {
if (!b) {
x = 1, y = 0;
return a;
}
int d = exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
struct Matrix {
int n, a[N][N]; Matrix(int _n = 0) {
n = _n;
memset(a, 0, sizeof(a));
} void operator ~(){
for (int i = 0; i < n; i++)
a[i][i] = 1;
} Matrix operator *(const Matrix &b) const {
Matrix sum(n);
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
for (int k = 0; k < n; k++)
sum.a[i][k] = (sum.a[i][k] + 1LL * a[i][j] * b.a[j][k] % Mo) % Mo;
return sum;
} Matrix operator^(long long p) const {
Matrix sum(n), x = *this;
~sum;
for (; p; p >>= 1, x = x * x)
if (p & 1) sum = sum * x;
return sum;
}
} ;

CDQ

#include<bits/stdc++.h>
using namespace std; const int N = 2e6 + 10; int n, k, b[N], tot, f[N]; struct Node {
int x, y, z, cnt, ans, id;
} a[N], c[N]; inline int read() {
int x = 0, k = 1; char ch = getchar();
for (; ch < 48 || ch > 57; ch = getchar()) k ^= (ch == '-');
for (; ch >= 48 && ch <= 57; ch = getchar()) x = x * 10 + (ch ^ 48);
return k ? x : -x;
} inline bool cmp (Node x, Node y) {
return x.x == y.x ? x.y == y.y ? x.z < y.z : x.y < y.y : x.x < y.x;
} inline bool pd_equal(Node x, Node y) {
return x.x != y.x || x.y != y.y || x.z != y.z;
} inline void add(int x, int val) {
for (; x <= k; x += (x & (-x)))
b[x] += val;
} inline int query(int x) {
int ans = 0;
for (; x; x -= (x & (-x)))
ans += b[x];
return ans;
} void CDQ(int l, int r) {
if (l == r)
return;
int mid = l + r >> 1;
CDQ(l, mid), CDQ(mid + 1, r);
for (int i = l, j = mid + 1, k = l; i <= mid || j <= r; k++)
if (j > r || (i <= mid && a[i].y <= a[j].y))
c[k] = a[i++];
else
c[k] = a[j++];
for (int i = l; i <= r; i++)
a[i] = c[i];
for (int i = l; i <= r; i++)
if (a[i].id <= mid)
add(a[i].z, a[i].cnt);
else
a[i].ans += query(a[i].z);
for (int i = l; i <= r; i++)
if (a[i].id <= mid)
add(a[i].z, -a[i].cnt);
} int main() {
n = read(), k = read();
for (int i = 1; i <= n; i++)
a[i].x = read(), a[i].y = read(), a[i].z = read();
std::sort(a + 1, a + 1 + n, cmp);
for (int i = 1; i <= n; i++)
if (!tot || pd_equal(a[i], a[i - 1]))
a[++tot] = a[i], a[tot].id = tot, a[tot].cnt = 1;
else
a[tot].cnt++;
CDQ(1, tot);
for (int i = 1; i <= tot; i++)
f[a[i].ans + a[i].cnt - 1] += a[i].cnt;
for (int i = 0; i < n; i++)
printf("%d\n", f[i]);
return 0;
}

回文自动机(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>
#define int long long
using namespace std;
const int N = 110;
const int M = 50;
int n;
long long x, a[N + 10], b[N +10], ANS;
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;
}
signed main() {
n = read();
for (int i = 1; i <= n; i++)
a[i] = read1();
std::sort(a + 1, a + 1 + n);
for (int i = 1; i <= n; i++)
if (check(a[i]))
ANS += a[i];
else
Insert(a[i]);
printf("%lld\n", ANS);
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)

SP3267 DQUERY - D-query

#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;
}

折半搜索 (9.30)

[CEOI2015 Day2]世界冰球锦标赛

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 10, M = 1 << 21;
int n;
long long aa[N], m;
long long suma[M], sumb[M], cnta, cntb;
long long ans;
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;
}
void dfs(int l, int r, long long sum, long long a[], long long &cnt) {
if (sum > m)
return;
if (l > r) {
a[++cnt] = sum;
return;
}
dfs(l + 1, r, sum + aa[l], a, cnt);
dfs(l + 1, r, sum, a, cnt);
}
signed main() {
n = read(), m = read1();
for (int i = 1; i <= n; i++)
aa[i] = read1();
dfs(1, n >> 1, 0, suma, cnta);
dfs((n >> 1) + 1, n, 0, sumb, cntb);
std::sort(suma + 1, suma + 1 + cnta);
for (int i = 1; i <= cntb; i++)
ans += upper_bound(suma + 1, suma + 1 +cnta, m - sumb[i]) - suma - 1;
printf("%lld", ans);
return 0;
}

树链剖分 (9.30)

题目

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10, M = N << 2;
int n, m, r, Mo, num, from[N], nxt[N], to[N], w[N], w1[N], a[M], lazy[M];
int son[N], id[N], father[N], depth[N], size[N], top[N], cnt, res;
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 void add(int x, int y) { // build tree
to[++num] = y, nxt[num] = from[x], from[x] = num;
}
void dfs1(int x, int fa, int deep) {
depth[x] = deep, father[x] = fa, size[x] = 1;
int maxx = -1; // find height son
for (int i = from[x]; i; i = nxt[i]) {
int y = to[i];
if (y == fa) // father
continue;
dfs1(y, x, deep + 1);
size[x] += size[y];
if (size[y] > maxx)
son[x] = y, maxx = size[y];
}
}
void dfs2(int x, int Top) { // link top
id[x] = ++cnt; // new number
w1[cnt] = w[x]; // new value
top[x] = Top;
if (!son[x]) return; //no sum
dfs2(son[x], Top);
for (int i = from[x]; i; i = nxt[i]) {
int y = to[i];
if (y == father[x] || y == son[x]) // father or height son
continue;
dfs2(y, y); // light son -> link top
}
} /*********Segment Tree***********/
inline void pushdown(int x, int y) {
int l = x << 1, r = x << 1 | 1;
lazy[l] += lazy[x], lazy[r] += lazy[x];
a[l] = (a[l] + lazy[x] * (y - (y >> 1))) % Mo;
a[r] = (a[r] + lazy[x] * (y >> 1)) % Mo;
lazy[x] = 0;
}
void build(int x, int l, int r) {
if (l == r) {
a[x] = w1[l] % Mo;
return;
}
build(x << 1, l, l + r >> 1);
build(x << 1 | 1, (l + r >> 1) + 1, r);
a[x] = (a[x << 1] + a[x << 1 | 1]) % Mo;
}
void query(int x, int l, int r, int L, int R) {
if (L <= l && R >= r) {
res = (res + a[x]) % Mo;
return;
}
if (lazy[x])
pushdown(x, r - l + 1);
if (L <= (l + r >> 1))
query(x << 1, l, l + r >> 1, L, R);
if (R > (l + r >> 1))
query(x << 1 | 1, (l + r >> 1) + 1, r, L, R);
} void update(int x, int l, int r, int L, int R, int k) {
if (L <= l && R >= r) {
lazy[x] += k, a[x] += k * (r - l + 1);
return;
}
if (lazy[x]) pushdown(x, r - l + 1);
if (L <= (l + r >> 1))
update(x << 1, l, l + r >> 1, L, R, k);
if (R > (l + r >> 1))
update(x << 1 | 1, (l + r >> 1) + 1, r, L, R, k);
a[x] = (a[x << 1] + a[x << 1 | 1]) % Mo;
}
/*********Segment Tree***********/ inline void addroad(int x, int y, int k) {
k %= Mo;
while (top[x] != top[y]) { // not same link
if (depth[top[x]] < depth[top[y]])
std::swap(x, y);
update(1, 1, n, id[top[x]], id[x], k);
x = father[top[x]];
}
if (depth[x] > depth[y])
std::swap(x, y);
update(1, 1, n, id[x], id[y], k);
}
inline int sumroad(int x, int y) {
int ans = 0;
while (top[x] != top[y]) {
if (depth[top[x]] < depth[top[y]])
std::swap(x, y);
res = 0;
query(1, 1, n, id[top[x]], id[x]);
ans = (ans + res) % Mo;
x = father[top[x]];
}
if (depth[x] > depth[y])
std::swap(x, y);
res = 0;
query(1, 1, n, id[x], id[y]);
return (ans + res) % Mo;
}
inline int sumson(int x) {
res = 0;
query(1, 1, n, id[x], id[x] + size[x] - 1);
return res;
}
inline void addson(int x, int k) {
update(1, 1, n, id[x], id[x] + size[x] - 1, k);
}
int main() {
n = read(), m = read(), r = read(), Mo = read();
for (int i = 1; i <= n; i++)
w[i] = read();
for (int i = 1; i < n; i++) {
int x = read(), y = read();
add(x, y), add(y, x);
}
dfs1(r, 0, 1);
dfs2(r, r);
build(1, 1, n);
while (m--) {
int opt = read(), x = read();
if (opt == 1) {
int y = read(), z = read();
addroad(x, y, z); // (x - y) path -> add z
}
else if (opt == 2) {
int y = read();
printf("%d\n", sumroad(x, y)); // (x - y) path -> sum
}
else if (opt == 3) {
int y = read();
addson(x, y); // subtree -> add z
}
else if (opt == 4)
printf("%d\n", sumson(x)); // subtree -> sum
}
return 0;
}

匈牙利算法 (10.2)

题目

#include<bits/stdc++.h>
using namespace std;
const int N = 2010;
int n, m, e, Match[N << 1], ans, ask[N << 1], head[N], cnt;
struct Node {
int to, nxt;
} edge[N * N];
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 void add(int u, int v) {
edge[++cnt] = (Node) {v, head[u]}, head[u] = cnt;
}
inline bool found(int x) {
for (int i = head[x]; i; i = edge[i].nxt) {
int y = edge[i].to;
if (ask[y]) continue;
ask[y] = 1;
if (!Match[y] || found(Match[y])) {
Match[y] = x;
return true;
}
}
return false;
}
inline void match() {
for (int i = 1; i <= n; i++) {
memset(ask, 0, sizeof(ask));
if (found(i))
ans++;
}
}
int main() {
n = read(), m = read(), e = read();
for (int i = 1; i <= e; i++) {
int u = read(), v = read();
if (v > m || u > n)
continue;
add(u, v + n);
}
match();
printf("%d\n", ans);
return 0;
}

Hopcroft-Karp (未)

//不是我的代码
/*
dx[i]表示左集合i顶点的距离编号
dy[i]表示右集合i顶点的距离编号
mx[i]表示左集合顶点所匹配的右集合顶点序号
my[i]表示右集合i顶点匹配到的左集合顶点序号
*/
#include <bits/stdc++.h>
#define N 1005
#define M 1000005
using namespace std;
inline int read()
{
register int x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*f;
}
inline void write(register int x)
{
if(!x)putchar('0');if(x<0)x=-x,putchar('-');
static int sta[25];int tot=0;
while(x)sta[tot++]=x%10,x/=10;
while(tot)putchar(sta[--tot]+48);
}
struct node{
int to,next;
}e[M];
int head[N],tot=0;
inline void add(register int u,register int v)
{
e[++tot]=(node){v,head[u]};
head[u]=tot;
}
int n,m,es,ans;
int dx[N],dy[N],mx[N],my[N],vis[N],dis;
inline bool bfs()
{
queue<int> q;
dis=1926081700;
memset(dx,-1,sizeof(dx));
memset(dy,-1,sizeof(dy));
for(register int i=1;i<=n;++i)
if(mx[i]==-1)
{
q.push(i);
dx[i]=0;
}
while(!q.empty())
{
int u=q.front();
q.pop();
if(dx[u]>dis)
break;
for(register int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(dy[v]==-1)
{
dy[v]=dx[u]+1;
if(my[v]==-1)
dis=dy[v];
else
{
dx[my[v]]=dy[v]+1;
q.push(my[v]);
}
}
}
}
return dis!=1926081700;
}
inline bool dfs(register int u)
{
for(register int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(vis[v]||(dy[v]!=dx[u]+1))
continue;
vis[v]=1;
if(my[v]!=-1&&dy[v]==dis)
continue;
if(my[v]==-1||dfs(my[v]))
{
my[v]=u;
mx[u]=v;
return true;
}
}
return false;
}
inline void match()
{
memset(mx,-1,sizeof(mx));
memset(my,-1,sizeof(my));
while(bfs())
{
memset(vis,0,sizeof(vis));
for(register int i=1;i<=n;++i)
if(mx[i]==-1&&dfs(i))
++ans;
}
}
int main()
{
n=read(),m=read(),es=read();
while(es--)
{
int u=read(),v=read();
if(v>m)
continue;
add(u,v);
}
match();
write(ans);
return 0;
}

Kuhn-Munkras (10.5)

hdu2255

#include<bits/stdc++.h>
using namespace std;
const int N = 110, INF = 0x3f3f3f3f;
bool tfg[N], tfb[N];
int b[N], g[N], a[N][N], match[N], slack[N], n;
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;
}
bool pd(int x) {
tfg[x] = true;
for (int i = 1; i <= n; i++) {
if (tfb[i])
continue;
int t = b[i] + g[x] - a[x][i];
if (t == 0) {
tfb[i] = true;
if (match[i] == -1 || pd(match[i])) {
match[i] = x;
return true;
}
}
else
slack[i] = std::min(slack[i], t);
}
return false;
}
inline void KM() {
memset(match, -1, sizeof(match));
memset(b, 0, sizeof(b));
for (int i = 1; i <= n; i++) {
g[i] = a[i][1];
for (int j = 2; j <= n; j++)
g[i] = std::max(g[i], a[i][j]);
}
for (int i = 1; i <= n; i++) {
fill(slack + 1, slack + n + 1, INF);
while (true) {
memset(tfb, false, sizeof(tfb));
memset(tfg, false, sizeof(tfg));
if (pd(i))
break;
int d = INF;
for (int j = 1; j <= n; j++)
if (!tfb[j])
d = std::min(d, slack[j]);
for (int j = 1; j <= n; j++) {
if (tfg[j])
g[j] -= d;
if (tfb[j]) b[j] += d; else slack[j] -= d;
}
}
}
}
int main() {
n = read();
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
a[i][j] = read();
KM();
int ans = 0;
for (int i = 1; i <= n; i++)
ans += a[match[i]][i];
printf("%d\n", ans);
return 0;
}

动态dp (10.7)

题目

yyb巨佬博客

#include<bits/stdc++.h>
using namespace std; const int INF = -0x3f, N = 1e5 + 10, M = 4e5 + 10; int n, m, cnt, head[N], to[M], nxt[M], siz[N], fa[N], val[N], son[N], cnt1, id[N], dfn[N], End[N], top1[N], f[N][2], L[N << 2], R[N << 2]; struct Matrix {
int mat[2][2]; Matrix() {
memset(mat, INF, sizeof(mat));
} inline Matrix operator * (Matrix b) {
Matrix a;
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
for (int k = 0; k < 2; k++)
a.mat[i][j] = std::max(a.mat[i][j], mat[i][k] + b.mat[k][j]);
return a;
} } Val[N << 2], a[N << 2]; 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 void add(int x, int y) {
to[++cnt] = y, nxt[cnt] = head[x], head[x] = cnt;
} void dfs1(int x) {
siz[x] = 1;
for (int i = head[x]; i; i = nxt[i]) {
int y = to[i];
if (y == fa[x])
continue;
fa[y] = x;
dfs1(y);
siz[x] += siz[y];
if (siz[y] > siz[son[x]]) // height son
son[x] = y;
}
} void dfs2(int x, int Top) {
id[x] = ++cnt1, dfn[cnt1] = x, top1[x] = Top, End[Top] = std::max(End[Top], cnt1);
f[x][0] = 0, f[x][1] = val[x];
Val[x].mat[0][0] = Val[x].mat[0][1] = 0, Val[x].mat[1][0] = val[x];
if (son[x] != 0) {
dfs2(son[x], Top);
f[x][0] += std::max(f[son[x]][0], f[son[x]][1]);
f[x][1] += f[son[x]][0];
}
for (int i = head[x]; i; i = nxt[i]) {
int y = to[i];
if (y== fa[x] || y == son[x])
continue;
dfs2(y, y);
f[x][0] += std::max(f[y][0], f[y][1]), f[x][1] += f[y][0];
Val[x].mat[0][0] += std::max(f[y][0], f[y][1]);
Val[x].mat[0][1] = Val[x].mat[0][0], Val[x].mat[1][0] += f[y][0];
}
} void Build(int l, int r, int x) {
L[x] = l, R[x] = r;
if (L[x] == R[x]) {
a[x] = Val[dfn[L[x]]];
return;
}
Build(L[x], L[x] + R[x] >> 1, x << 1);
Build((L[x] + R[x] >> 1) + 1, R[x], x << 1 | 1);
a[x] = a[x << 1] * a[x << 1 | 1];
} void update(int x, int i) {
if (L[i] == R[i]) {
a[i] = Val[dfn[x]];
return;
}
if (x <= (L[i] + R[i] >> 1))
update(x, i << 1);
else
update(x, i << 1 | 1);
// update(x, (x <= (L[i] + R[i] >> 1)) ? (i << 1) : (i << 1 | 1));
a[i] = a[i << 1] * a[i << 1 | 1];
} Matrix query(int l, int r, int x) {
if (L[x] == l && R[x] == r)
return a[x];
int mid = L[x] + R[x] >> 1;
if (r <= mid) return query(l, r, x << 1);
else if (l > mid) return query(l, r, x << 1 | 1);
else return query(l, mid, x << 1) * query(mid + 1, r, x << 1 | 1);
} void update_path(int x, int y) {
Val[x].mat[1][0] += y - val[x], val[x] = y;
Matrix a, b;
while (x != 0) {
a = query(id[top1[x]], End[top1[x]], 1);
update(id[x], 1);
b = query(id[top1[x]], End[top1[x]], 1), x = fa[top1[x]];
Val[x].mat[0][0] += std::max(b.mat[0][0], b.mat[1][0]) - std::max(a.mat[0][0], a.mat[1][0]), Val[x].mat[0][1] = Val[x].mat[0][0];
Val[x].mat[1][0] += b.mat[0][0] - a.mat[0][0];
}
} int main() {
n = read(), m = read();
for (int i = 1; i <= n; i++)
val[i] = read();
for (int i = 1; i < n; i++) {
int x = read(), y = read();
add(x, y), add(y, x);
}
dfs1(1);
dfs2(1, 1);
Build(1, n, 1);
for (int i = 1; i <= m; i++) {
int x = read(), y = read();
update_path(x, y);
Matrix ans = query(id[1], End[1], 1);
printf("%d\n", std::max(ans.mat[0][0], ans.mat[1][0]));
}
return 0;
}

缩点(10.8)

CF734E Anton and Tree

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10; int n, color[N];
vector<int> a[N]; 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;
} pair<int, int> dfs(int x, int fa, int depth) {
int sz = a[x].size();
pair<int, int> tmp = make_pair(depth, x);
for (int i = 0; i < sz; i++) {
int y = a[x][i];
if (y == fa)
continue;
if(color[y] != color[x])
tmp = std::max(tmp, dfs(y, x, depth + 1));
else
tmp = std::max(tmp, dfs(y, x, depth));
}
return tmp;
} int main() {
n = read();
for (int i = 1; i <= n; i++)
color[i] = read();
for (int i = 1; i < n; i++) {
int x = read(), y = read();
a[x].push_back(y), a[y].push_back(x);
}
pair<int, int> tmp = dfs(1, -1, 0);
tmp = dfs(tmp.second, -1, 0);
printf("%d\n", tmp.first + 1 >> 1);
}

Lucas (10.9)

inline long long ksm(long long a, long long b) {
long long ans = 1;
a = a % Mo;
for (; b; b >>= 1, a = a * a % Mo)
if (b & 1) ans = ans * a % Mo;
return ans;
} inline long long C(long long n, long long m) {
if (m > n) return 0;
long long a = 1, b = 1;
for (long long i = 1; i <= m; i++)
a = a * (n + i - m) % Mo, b = b * i % Mo;
return a * ksm(b, Mo - 2) % Mo;
} inline long long Lucas(long long n, long long m) {
long long ans = 1;
for (; n && m; n /= Mo, m /= Mo)
ans = ans * C(n % Mo, m % Mo);
return ans;
}

Simpson 1(10.9)

题目

#include<bits/stdc++.h>
using namespace std; const double Eps = 1e-6; double a, b, c, d, L, R; inline double f(double x) {
return (c * x + d) / (a * x + b);
} inline double Simpson(double L, double R) {
double mid = (L + R) / 2;
return ((R - L) * (f(L) + f(R) + 4 * f(mid))) / 6.0;
} inline double Solve(double L, double R, double eps, double ans) {
double mid = (L + R) / 2;
double l = Simpson(L, mid), r = Simpson(mid, R);
if (fabs(l + r - ans) <= eps * 15)
return l + r + (l + r - ans) / 15;
return Solve(L, mid, eps / 2, l) + Solve(mid, R, eps / 2, r);
} inline double Solve(double L, double R, double eps) {
return Solve(L, R, eps, Simpson(L, R));
} int main() {
scanf("%lf%lf%lf%lf%lf%lf", &a, &b, &c, &d, &L, &R);
printf("%.6f", Solve(L, R, Eps));
return 0;
}

Simpson 2 (10.10)

#include<bits/stdc++.h>
using namespace std; const double Eps = 1e-8; double a, b, c, d, L, R; inline double f(double x) {
return pow(x, a / x - x);
} inline double Simpson(double L, double R) {
double mid = (L + R) / 2;
return ((R - L) * (f(L) + f(R) + 4 * f(mid))) / 6.0;
} inline double Solve(double L, double R, double eps, double ans) {
double mid = (L + R) / 2;
double l = Simpson(L, mid), r = Simpson(mid, R);
if (fabs(l + r - ans) <= eps * 15)
return l + r + (l + r - ans) / 15;
return Solve(L, mid, eps / 2, l) + Solve(mid, R, eps / 2, r);
} inline double Solve(double a, double b) {
return Solve(a, b, Eps, Simpson(a, b));
} int main() {
scanf("%lf", &a);
if (a < 0)
return puts("orz"), 0;
printf("%.5f", Solve(Eps, 20.0));
return 0;
}

\(\mathcal{01trie}\)

题目

#include<bits/stdc++.h>
#define pow(x, i) (x >> i)
using namespace std; const int N = 6e6 + 10, M = 30; int cnt[N], trie[N][2], tot = 1, n; 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 void add(int x, int dg) {
int p = 1;
for (int i = M; i >= 0; --i) {
if (dg == 1) trie[p][(pow(x, i) & 1)] = (trie[p][(pow(x, i) & 1)] != 0) ? trie[p][(pow(x, i) & 1)] : (++tot);
p = trie[p][(pow(x, i) & 1)], cnt[p] += dg;
}
} inline int ask(int x, int y) {
int p = 1;
int sum = 0;
for (int i = M; i >= 0; i--) {
int t = (pow(y, i) & 1), t1 = (pow(x, i) & 1);
if (t)
sum += cnt[trie[p][t1]], p = trie[p][t1 ^ 1];
else
p = trie[p][t1];
}
return sum;
} int main() {
n = read();
while (n--) {
int opt = read(), x = read();
if (opt == 1)
add(x, 1);
else if (opt == 2)
add(x, -1);
else if (opt == 3) {
int y = read();
printf("%d\n", ask(x, y));
}
}
return 0;
}

树的重心

#include<bits/stdc++.h>
using namespace std; const int N = 3e5 + 10; struct Node {
int to, nxt;
} edge[N << 1]; int cnt, n, m, Fa[N], sz[N], ans[N], head[N]; 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 void Build(int x, int y) {
edge[++cnt].to = x, edge[cnt].nxt = head[y], head[y] = cnt;
} void dfs(int x, int fa) {
int res = 0;
sz[x] = 1, ans[x] = x;
for (int i = head[x]; i; i = edge[i].nxt) {
int y = edge[i].to;
if (y == fa)
continue;
dfs(y, x);
sz[x] += sz[y], res = (sz[y] > sz[res]) ? y : res;
} if ((sz[res] << 1) > sz[x])
for (ans[x] = ans[res]; ((sz[x] - sz[ans[x]]) << 1) > sz[x]; ans[x] = Fa[ans[x]]);
} int main() {
n = read(), m = read();
for (int i = 2; i <= n; i++) {
Fa[i] = read();
Build(i, Fa[i]);
Build(Fa[i], i);
} dfs(1, 0); while (m--) {
int x = read();
printf("%d\n", ans[x]);
}
return 0;
}

二分图多重匹配(未)

链接

WQS 二分 (未)

学习链接

ZAGER

最新文章

  1. CORS简介
  2. Linux下,拷贝文件时,排除某些文件
  3. [转]浏览器退出之后php还会继续执行么?
  4. HTC Vive 体验的折腾经历
  5. HashCode作用
  6. 【转】搭建Python的Eclipse开发环境之安装PyDev插件--离线安装
  7. MAT(1) 小样
  8. 配置oschina for pc 开发环境
  9. ASP.NET之JSONHelper操作
  10. 【MongoDB】应用场景
  11. Normalize.css 介绍与源码解读
  12. Akamai在内容分发网络中的算法研究(翻译总结)
  13. karma测试实践
  14. html固定表头,表单内容垂直循环滚动
  15. TCP/IP协议---ICMP协议及ping、traceroute
  16. 关于Androidstudio无法获取到所有的SDk版本,需要挂国内镜像的问题
  17. [javascript] 看知乎学习js闭包
  18. An Introduction to Protocol Oriented Programming in Swift
  19. vue项目实现列表页-详情页返回不刷新,再点其他菜单项返回刷新的需求
  20. weblogic学习笔记:域创建+应用部署

热门文章

  1. 力扣—Reorder List(重排链表)python实现
  2. SVN连接不上仓库,问题之一
  3. 学习selenium grid记录
  4. 10.ThreadLocal
  5. vs code常用插件(python)
  6. px4的CMakelists.txt阅读
  7. Database基础(四):密码恢复及设置、 用户授权及撤销、数据备份与恢复、MySQL管理工具
  8. 容器————priority_queue
  9. linux基础知识汇总(二)-vi/vim
  10. HDU 6625 three arrays 求两个序列异或最小值的排列(一个可以推广的正解