芋艿酱的自用板子
文件模板 1
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define R(i, a, b) for (int i = (a); i <= (b); ++i)
#define P(i, a, b) for (int i = (b); i >= (a); --i)
#define F(v, x...) for (auto x : v)
#define G(x, head, e) for (int i = head[x]; i; i = e[i].ne)
#define Gt(x, tn, head, e) for (int i = head[x], tn = e[i].to; i; i = e[i].ne, tn = e[i].to)
#define Gw(x, tn, w, head, e) for (int i = head[x], tn = e[i].to, w = e[i].w; i; i = e[i].ne, tn = e[i].to, w = e[i].w)
#define lb(a) for (; a; a -= (a & -a))
#define lc(x, a) for (; x <= a; x += (x & -x))
#define debug(msg...) fprintf(stderr, ##msg)
char buf[1 << 20], *p1 = buf, *p2 = buf;
#define getc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 20, stdin), p1 == p2) ? EOF : *p1++)
#define putc(x) putchar(x)
#define Yes() putc('Y'), putc('e'), putc('s'), putc('\n')
#define YES() putc('Y'), putc('E'), putc('S'), putc('\n')
#define No() putc('N'), putc('o'), putc('\n')
#define NO() putc('N'), putc('O'), putc('\n')
inline ll read() {
ll x = 0, sgn = 0; char s = getc();
while(!isdigit(s)) sgn |= s == '-', s = getc();
while(isdigit(s)) x = x * 10 + s - '0', s = getc();
return sgn ? -x : x;
}
inline void print(ll x) { if (x < 0) { putc('-'), print(-x); return; } if(x >= 10) print(x / 10); putc(x % 10 + '0'); }
bool Mbe;
void solve() {
}
bool Med;
int main() {
// int t = 1;
int t = read();
while (t--) solve();
fprintf(stderr, "\n%.3lf MB\n", (&Mbe - &Med) / 1048576.0);
return 0;
}
文件模板 2
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
char buf[1 << 20], *p1 = buf, *p2 = buf;
#define getc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 20, stdin), p1 == p2) ? EOF : *p1++)
#define putc(x) putchar(x)
inline ll read() {
ll x = 0, sgn = 0; char s = getc();
while(!isdigit(s)) sgn |= s == '-', s = getc();
while(isdigit(s)) x = x * 10 + s - '0', s = getc();
return sgn ? -x : x;
}
inline void print(ll x) { if (x < 0) { putc('-'), print(-x); return; } if(x >= 10) print(x / 10); putc(x % 10 + '0'); }
int main() {
return 0;
}
快读
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define per(i, a, b) for (int i = (b); i >= (a); --i)
#define go(x) for (int i = head[x], tn = e[i].to; i; i = e[i].ne, tn = e[i].to)
using ll = long long;
inline ll read(ll& x) {
x = 0;
int f = 0, c = getchar();
for (; c < 48 || c > 57; c = getchar()) f |= c == 45;
for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + c - 48;
return x;
}
inline int read() {
int x = 0, f = 0, c = getchar();
for (; c < 48 || c > 57; c = getchar()) f |= c == 45;
for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + c - 48;
return x;
}
Pollard-Rho 快速分解素因数
namespace prime_fac {
const int S = 8;
long long mult_mod(long long a, long long b, long long c) {
a %= c, b %= c;
long long ret = 0;
long long tmp = a;
while (b) {
if (b & 1) {
ret += tmp;
if (ret > c) ret -= c;
}
tmp <<= 1;
if (tmp > c) tmp -= c;
b >>= 1;
}
return ret;
}
long long qow_mod(long long a, long long n, long long _mod) {
long long ret = 1;
long long temp = a % _mod;
while (n) {
if (n & 1) ret = mult_mod(ret, temp, _mod);
temp = mult_mod(temp, temp, _mod);
n >>= 1;
}
return ret;
}
bool check(long long a, long long n, long long x, long long t) {
long long ret = qow_mod(a, x, n);
long long last = ret;
for (int i = 1; i <= t; i++) {
ret = mult_mod(ret, ret, n);
if (ret == 1 && last != 1 && last != n - 1) return true;
last = ret;
}
if (ret != 1) return true;
return false;
}
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
bool Miller_Rabin(long long n) {
if (n < 2) return false;
if (n == 2) return true;
if ((n & 1) == 0) return false;
long long x = n - 1;
long long t = 0;
while ((x & 1) == 0) { x >>= 1; t++; }
for (int i = 0; i < S; i++) {
long long a = rng() % (n - 1) + 1;
if (check(a, n, x, t))
return false;
}
return true;
}
long long factor[100];
int tol;
long long gcd(long long a, long long b) {
long long t;
while (b) {
t = a;
a = b;
b = t % b;
}
if (a >= 0) return a;
return -a;
}
long long pollard_rho(long long x, long long c) {
long long i = 1, k = 2;
long long x0 = rng() % (x - 1) + 1;
long long y = x0;
while (1) {
i++;
x0 = (mult_mod(x0, x0, x) + c) % x;
long long d = gcd(y - x0, x);
if (d != 1 && d != x) return d;
if (y == x0) return x;
if (i == k) { y = x0; k += k; }
}
}
void findfac(long long n, int k) {
if (n == 1) return;
if (Miller_Rabin(n)) {
factor[tol++] = n;
return;
}
long long p = n;
int c = k;
while (p >= n) p = pollard_rho(p, c--);
findfac(p, k);
findfac(n / p, k);
}
vector<int> fac(long long n) {
tol = 0;
vector<int>ret;
findfac(n, 107);
for (int i = 0; i < tol; i++) ret.push_back(factor[i]);
return ret;
}
}
function递归
std::function<void(int)> dfs = [&](int x) {
if (x) printf("%d ", x), dfs(t[x][0]), dfs(t[x][1]);
};
图结构类
struct graph {
graph(int n) : head(n + 1, 0) {}
std::vector<std::array<int, 3>> e = {{0, 0}};
int cnt = 0;
std::vector<int> head;
void add(int x, int y) {
e.push_back({y, head[x]}), head[x] = ++cnt;
};
};
fenwick
ll c[2][N], sum[N];
void add(int k, int p, ll x) { for (; p <= n; p += (p & -p)) c[k][p] += x; }
ll ask(int k, int p) {
ll ans = 0;
for (; p; p -= (p & -p)) ans += c[k][p];
return ans;
}
整体二分
P7424
给定 n 条线段,每次询问给出一个位置,求该位置被多少条线段覆盖,并阶段它们。
int n, m;
struct que {
int l, r, k, typ, id;
} q[N], q1[N], q2[N];
int c[N], ans[N];
void add(int p, int x) { for (; p <= 2e5; p += p & -p) c[p] += x; }
int ask(int p) { int res = 0; for (; p; p -= p & -p) res += c[p]; return res; }
void solve(int l, int r, int L, int R) {
if (l > r) return;
if (L == R) {
for (int i = l; i <= r; ++i) if (q[i].typ) ++ans[L];
return;
}
int mid = L + R >> 1, p1 = 0, p2 = 0;
for (int i = l; i <= r; ++i) {
if (q[i].typ) {
int sum = ask(q[i].r) - ask(q[i].l - 1);
if (sum >= q[i].k) q1[++p1] = q[i];
else q[i].k -= sum, q2[++p2] = q[i];
} else {
if (q[i].id <= mid) add(q[i].l, 1), q1[++p1] = q[i];
else q2[++p2] = q[i];
}
}
for (int i = 1; i <= p1; ++i) if (!q1[i].typ) add(q1[i].l, -1);
for (int i = 1; i <= p1; ++i) q[l + i - 1] = q1[i];
for (int i = 1; i <= p2; ++i) q[l + p1 + i - 1] = q2[i];
solve(l, l + p1 - 1, L, mid);
solve(l + p1, l + p1 + p2 - 1, mid + 1, R);
}
int main() {
read(n, m);
for (int i = 1; i <= n; ++i) {
int l, r, v;
read(l, r, v);
q[m + i] = {l, r, v, 1, i};
}
for (int i = 1; i <= m; ++i) {
int x = read();
q[i] = {x, 0, 0, 0, i};
}
solve(1, m + n, 1, m + 1);
for (int i = 1; i <= m; ++i) printf("%d\n", ans[i]);
return 0;
}
三维偏序
给定 ${a_n}$,${b_n}$,${c_n}$,求 $f_i$ 的值,其中 $f_i$ 表示满足 $a_j \leq a_i$,$b_j \leq b_i$,$c_j \leq c_i$ 的 j 的数量。
CDQ 分治
int n, k;
struct ele {
int a, b, c, d, res;
bool operator<(ele x) const {
return a != x.a ? a < x.a : (b != x.b ? b < x.b : c < x.c);
}
bool operator==(ele x) const {
return a == x.a && b == x.b && c == x.c;
}
} _[N], e[N];
int cnt[N], c[N];
void add(int p, int x) { for (; p <= k; p += p & -p) c[p] += x; }
int ask(int p) { int res = 0; for (; p; p -= p & -p) res += c[p]; return res; }
void cdq(int l, int r) {
if (l == r) return;
int mid = l + r >> 1;
cdq(l, mid), cdq(mid + 1, r);
auto func = [&](auto x, auto y) { return x.b != y.b ? x.b < y.b : x.c < y.c; };
sort(e + l, e + mid + 1, func);
sort(e + mid + 1, e + r + 1, func);
int j = l, k = mid + 1;
for (; k <= r; ++k) {
for (; j <= mid && e[j].b <= e[k].b; ++j)
add(e[j].c, e[j].d);
e[k].res += ask(e[k].c);
}
for (int i = l; i < j; ++i) add(e[i].c, -e[i].d);
}
int main() {
read(n, k);
for (int i = 1; i <= n; ++i) read(_[i].a, _[i].b, _[i].c);
sort(_ + 1, _ + n + 1);
int sum = 1, tot = 0;
for (int i = 1; i <= n; ++i) {
if (_[i + 1] == _[i]) {
++sum;
continue;
}
e[++tot] = _[i], e[tot].d = sum;
sum = 1;
}
cdq(1, tot);
for (int i = 1; i <= tot; ++i) cnt[e[i].d + e[i].res - 1] += e[i].d;
for (int i = 0; i < n; ++i) printf("%d\n", cnt[i]);
return 0;
}
树套树
#define R(i, a, b) for (int i = (a); i <= (b); ++i)
#define lb(a) for (; a; a -= (a & -a))
#define lc(x, a) for (; x <= a; x += (x & -x))
int n, k;
struct ele {
int a, b, c;
bool operator<(ele x) const {
return a != x.a ? a < x.a : (b != x.b ? b < x.b : c < x.c);
}
bool operator==(ele x) const {
return a == x.a && b == x.b && c == x.c;
}
} e[100007];
struct node {
int l, r;
int val;
#define l(p) tr[p].l
#define r(p) tr[p].r
#define val(p) tr[p].val
} tr[200007 * 80];
int tot, root[200007];
int modify(int now, int x, int v, int l, int r) {
int p = ++tot;
tr[p] = tr[now];
if (l == r) {
val(p) += v;
return p;
}
int mid = l + r >> 1;
if (x <= mid) l(p) = modify(l(now), x, v, l, mid);
else r(p) = modify(r(now), x, v, mid + 1, r);
val(p) = val(l(p)) + val(r(p));
return p;
}
int query(int now, int l, int r, int L, int R) {
if (l <= L && r >= R) return val(now);
int mid = L + R >> 1, ans = 0;
if (l <= mid) ans += query(l(now), l, r, L, mid);
if (r > mid) ans += query(r(now), l, r, mid + 1, R);
return ans;
}
void update(int x, int y, int v) {
lc(x, k) root[x] = modify(root[x], y, v, 1, k);
}
int ask(int x, int y) {
int ans = 0;
lb(x) ans += query(root[x], 1, y, 1, k);
return ans;
}
int cnt[100007];
int main() {
n = read(), k = read();
R(i, 1, n) e[i].a = read(), e[i].b = read(), e[i].c = read();
sort(e + 1, e + n + 1);
int sum = 1;
R(i, 1, n) {
if (e[i + 1] == e[i]) {
++sum;
continue;
}
update(e[i].b, e[i].c, sum);
cnt[ask(e[i].b, e[i].c)] += sum;
sum = 1;
}
R(i, 1, n) print(cnt[i]), putc('\n');
return 0;
}
线段树合并
给定一棵树,有 m 次询问。每次询问给出一条路径,路径上所有的点上存下一个给定的数字。求每个节点上出现频率最多的数字是什么。
struct node {
int l, r;
int val, id;
#define l(p) tr[p].l
#define r(p) tr[p].r
#define val(p) tr[p].val
#define id(p) tr[p].id
} tr[100007 * 300];
int n, m, tot, root[100007];
int insert(int now, int x, int v, int l = 1, int r = 1e5) {
int p = ++tot;
tr[p] = tr[now];
if (l == r) {
val(p) += v;
id(p) = l;
return p;
}
int mid = l + r >> 1;
if (x <= mid) l(p) = insert(l(now), x, v, l, mid);
else r(p) = insert(r(now), x, v, mid + 1, r);
if (val(l(p)) >= val(r(p))) val(p) = val(l(p)), id(p) = id(l(p));
else val(p) = val(r(p)), id(p) = id(r(p));
return p;
}
int merge(int a, int b, int l = 1, int r = 1e5) {
if (!a) return b;
if (!b) return a;
if (l == r) {
val(a) += val(b);
id(a) = l;
return a;
}
int mid = l + r >> 1;
l(a) = merge(l(a), l(b), l, mid);
r(a) = merge(r(a), r(b), mid + 1, r);
if (val(l(a)) >= val(r(a))) val(a) = val(l(a)), id(a) = id(l(a));
else val(a) = val(r(a)), id(a) = id(r(a));
return a;
}
struct edge {
int to, ne;
} e[100007 * 2];
int cnt, dfn, eul[100007 * 2], loc[100007], f[100007], dep[100007], head[100007];
void preDfs(int x, int fa) {
eul[++dfn] = x, loc[x] = dfn, f[x] = fa, dep[x] = dep[fa] + 1;
for (int i = head[x]; i; i = e[i].ne) {
int tn = e[i].to;
if (tn == fa) continue;
preDfs(tn, x);
eul[++dfn] = x;
}
}
int mn[100007 * 8];
void build(int p, int l, int r) {
if (l == r) {
mn[p] = eul[l];
return;
}
int mid = l + r >> 1;
build(p << 1, l, mid), build(p << 1 | 1, mid + 1, r);
mn[p] = dep[mn[p << 1]] < dep[mn[p << 1 | 1]] ? mn[p << 1] : mn[p << 1 | 1];
}
int ask(int l, int r, int p = 1, int L = 1, int R = dfn) {
if (L > r || R < l) return -1;
if (L >= l && R <= r) return mn[p];
int mid = L + R >> 1;
int lans = ask(l, r, p << 1, L, mid);
int rans = ask(l, r, p << 1 | 1, mid + 1, R);
if (lans == -1 || rans == -1) return lans + rans + 1;
return dep[lans] < dep[rans] ? lans : rans;
}
int lca(int x, int y) {
int l = loc[x], r = loc[y];
if (l > r) swap(l, r);
return ask(l, r);
}
int ans[100007];
void dfs(int x, int fa) {
for (int i = head[x]; i; i = e[i].ne) {
int tn = e[i].to;
if (tn == fa || dep[tn] <= dep[x]) continue;
dfs(tn, x);
root[x] = merge(root[x], root[tn]);
}
if (val(root[x])) ans[x] = id(root[x]);
}
int main() {
scanf("%d %d", &n, &m);
for (int i = 1, x, y; i < n; ++i) {
scanf("%d %d", &x, &y);
e[++cnt] = {y, head[x]}, head[x] = cnt;
e[++cnt] = {x, head[y]}, head[y] = cnt;
}
preDfs(1, 0);
build(1, 1, dfn);
for (int i = 1, x, y, z; i <= m; ++i) {
scanf("%d %d %d", &x, &y, &z);
int lc = lca(x, y);
root[x] = insert(root[x], z, 1), root[y] = insert(root[y], z, 1);
root[lc] = insert(root[lc], z, -1);
if (f[lc]) root[f[lc]] = insert(root[f[lc]], z, -1);
}
dfs(1, 0);
for (int i = 1; i <= n; ++i) printf("%d\n", ans[i]);
return 0;
}
普通莫队
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int n, m, B, res, col[50007], cnt[50007];
struct Q {
int id, l, r;
bool operator<(Q x) const {
return l / B == x.l / B ? (r == x.r ? 0 : ((l / B) & 1) ^ (r < x.r)) : l < x.l;
}
} que[50007];
struct A {
ll p, q;
string k;
} ans[50007];
void move(int val, int sign) {
sign ? res += cnt[val]++ : res -= --cnt[val];
}
int main() {
scanf("%d %d", &n, &m);
B = sqrt(m);
for (int i = 1; i <= n; ++i) scanf("%d", &col[i]);
for (int i = 1; i <= m; ++i) {
int& l = que[i].l;
int& r = que[i].r;
int& id = que[i].id;
scanf("%d %d", &l, &r);
id = i;
}
sort(que + 1, que + m + 1);
for (int i = 1, l = 1, r = 0; i <= m; ++i) {
int L = que[i].l, R = que[i].r;
if (L == R) {
ans[que[i].id] = {0, 1};
continue;
}
while (l > L) move(col[--l], 1);
while (r < R) move(col[++r], 1);
while (l < L) move(col[l++], 0);
while (r > R) move(col[r--], 0);
ans[que[i].id] = {res, 1ll * (r - l + 1) * (r - l) / 2};
}
for (int i = 1; i <= m; ++i) {
ll tmpP = ans[que[i].id].p, tmpQ = ans[que[i].id].q;
if (!tmpP) {
ans[que[i].id].k = "0/1";
continue;
}
ll g = __gcd(tmpP, tmpQ);
tmpP /= g, tmpQ /= g;
ans[que[i].id].k = to_string(tmpP) + "/" + to_string(tmpQ);
}
for (int i = 1; i <= m; ++i) printf("%s\n", &ans[i].k[0]);
return 0;
}
集合哈希
struct randomhash {
static uint64_t splitmix64(uint64_t x) {
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
};
class SetHasher {
unordered_map<int, ull, randomhash> elemHash;
mt19937_64 rng;
public:
SetHasher():rng(chrono::steady_clock::now().time_since_epoch().count()) {}
ull getelemhash(const int &elem){
if (!elemHash.count(elem)){
elemHash[elem] = rng();
}
return elemHash[elem];
}
ull computexorhash(const vector<int> &elem){
ull x = 0;
for (const auto &e: elem){
x ^= getelemhash(e);
}
return x;
}
ull add(ull curhash, const int &elem) {
return curhash ^ getelemhash(elem);
}
};
void solve(){
SetHasher sh;
int n; cin>>n;
vector<int> a(n + 1, 0), b(n + 1, 0),c(n + 1,0);
vector<int> ma, mb, mc;
ma.reserve(n);
mb.reserve(n);
mc.reserve(n);
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) cin >> b[i];
for (int i = 1; i <= n; i++) cin >> c[i];
int cnt=0;
ull ha = 0, hb = 0, hc = 0;
for (int i = 1; i <= n; i++){
ha = sh.add(ha, a[i]);
hb = sh.add(hb, b[i]);
hc = sh.add(hc, c[i]);
if(ha == hb || ha == hc || hb == hc){
cnt++;
}
}
cout << cnt << '\n';
}