算法模板(乱序)
树状数组
template <typename T>
class fenwick {
public:
vector<T> fenw;
int n;
fenwick(int _n) : n(_n) {
fenw.resize(n);
}
void modify(int x, T v) {
while (x < n) {
fenw[x] += v;
x |= (x + 1);
}
}
T get(int x) {
T v{};
while (x >= 0) {
v += fenw[x];
x = (x & (x + 1)) - 1;
}
return v;
}
T get(int l, int r) {
return get(r) - get(l - 1);
}
};
并查集 DSU
struct DSU {
vector<int> f, siz, rank;
int cnt; //统计还剩多少个连通块
DSU(int n) : cnt(n), f(n), rank(n, 0), siz(n, 1) { iota(f.begin(), f.end(), 0); }
int find(int x) {
while (x != f[x]) x = f[x] = f[f[x]];
return x;
}
bool same(int x, int y) { return find(x) == find(y); }
int merge(int x, int y) {
x = find(x), y = find(y);
if (x == y) return -1;
else -- cnt;
if(rank[x] > rank[y]) swap(x, y);
siz[y] += siz[x];
f[x] = y;
if(rank[x] == rank[y]) rank[y] ++;
return y;
}
int size(int x) { return siz[find(x)]; }
}; //按秩合并 and 路径压缩
dijkstra
template <typename T> //son[].second (int or ll)
vector<T> dijkstra(vector<vector<pair<int, int> > > &son, int n, int Start = 0) {
struct node { int u; T d; bool operator < (const node &Tnode) const {
return d > Tnode.d;
}
};
priority_queue<node> q;
vector<int> st(n); vector<T> dist(n, INT_MAX); //最大值修改一下
q.push({Start, 0}); dist[Start] = 0;
while (not q.empty()) {
auto [u, d] = q.top(); q.pop();
if (st[u]) continue; st[u] = 1;
for (auto &[v, w]: son[u]) {
if (d + w < dist[v]) {
dist[v] = d + w;
q.push({v, d + w});
}
}
}
return dist;
}
void solve() {
int n, m; cin >> n >> m;
vector<vector<pair<int, int> > > son(n);
for (int i = 1, u, v, w; i <= m; i++ ) {
cin >> u >> v >> w; u --, v --;
son[u].push_back(make_pair(v, w));
}
auto dist = dijkstra<ll>(son, n);
if (dist.back() > 1E9) dist.back() = -1;
cout << dist.back();
}
快读
struct FastIO{//不可与scanf,printf,getchar,putchar,gets,puts,cin,cout混用
private:
static const int BUFSIZE=1e5;
char buf[BUFSIZE];int pos,len;//读入buffer(缓冲器)以及读入指针
int wpos;char wbuf[BUFSIZE];//输出指针以及输出buffer
#define gc() (pos==len&&(len=(pos=0)+fread(buf,1,BUFSIZE,stdin),!len)?EOF:buf[pos++])
#define pc(c) (wpos==BUFSIZE?fwrite(wbuf,1,BUFSIZE,stdout),wpos=0,wbuf[wpos++]=c:wbuf[wpos++]=c)
public:
FastIO():wpos(0),pos(0),len(0){}
~FastIO(){if(wpos)fwrite(wbuf,1,wpos,stdout),wpos=0;}
inline char getc(){return gc();}//读取char
inline void putc(char c){pc(c);}//输出字符
inline long long rd(){//读取long long
long long x=0;char c=gc();bool f=0;
for(;c<'0'||c>'9';c=gc())f|=c=='-';
for(;c>='0'&&c<='9';c=gc())x=(x<<3)+(x<<1)+(c^48);
return f?-x:x;
}
template<typename T>inline bool read(T &x){//多测读整数while(io.read(n))work();本地测试请输入两次ctrl Z
x=0;char c=gc();bool f=0;
for(;c<'0'||c>'9';c=gc()){if(c==EOF)return false;f|=c=='-';}
for(;c>='0'&&c<='9';c=gc())x=(x<<3)+(x<<1)+(c^48);
if(f)x=-x;return true;
}
inline void wt(long long x){//输出整数
if(x<0)pc('-'),x=-x;
char a[20];short int h=0;
for(a[++h]='0'+x%10,x/=10;x;x/=10)a[++h]='0'+x%10;
for(;h;)pc(a[h--]);
}
inline void wtl(long long x){wt(x);pc('\n');}//write line输出整数并换行
inline void wtb(long long x){wt(x);pc(' ');}//write blank输出整数并空格
inline int gets(char s[]){int l=0;char c=gc();for(;c<=' ';c=gc());for(;c>' ';c=gc())s[l++]=c;s[l]=0;return l;}
inline void puts(const char *s){for(const char *p=s;*p;)pc(*p++);}//输出字符串 (不带换行)
template<typename T>inline FastIO & operator >> (T &a){return read(a),*this;}//io>>a>>b;只能输入整数
inline FastIO & operator << (long long a){return wtb(a),*this;}//io<<a<<b;输出整数并带有空格
}io;
取模函数
const int MOD = 998244353;
inline int mod(int x) {return x >= MOD ? x - MOD : x;}
inline int ksm(int a, int b) {
int ret = 1; a = mod(a);
for(; b; b >>= 1, a = 1LL * a * a % MOD) if(b & 1) ret = 1LL * ret * a % MOD;
return ret;
}
template<int MOD>
struct modint {
int x;
modint() {x = 0; }
modint(int y) {x = y;}
inline modint inv() const { return modint{ksm(x, MOD - 2)}; }
explicit inline operator int() { return x; }
friend inline modint operator + (const modint &a, const modint& b) { return modint(mod(a.x + b.x)); }
friend inline modint operator - (const modint &a, const modint& b) { return modint(mod(a.x - b.x + MOD)); }
friend inline modint operator * (const modint &a, const modint& b) { return modint(1ll * a.x * b.x % MOD); }
friend inline modint operator / (const modint &a, const modint& b) { return modint(1ll * a.x * b.inv().x % MOD); }
friend inline modint operator - (const modint &a) { return modint(mod(MOD - a.x)); }
friend inline modint& operator += (modint &a, const modint& b) { return a = a + b; }
friend inline modint& operator -= (modint &a, const modint& b) { return a = a - b; }
friend inline modint& operator *= (modint &a, const modint& b) { return a = a * b; }
friend inline modint& operator /= (modint &a, const modint& b) { return a = a / b; }
friend auto &operator >> (istream &i, modint &a) {return i >> a.x; }
friend auto &operator << (ostream &o, const modint &z) { return o << z.x; }
inline bool operator == (const modint &b) { return x == b.x; }
inline bool operator != (const modint &b) { return x != b.x; }
inline bool operator < (const modint &a) { return x < a.x; }
inline bool operator <= (const modint &a) { return x <= a.x; }
inline bool operator > (const modint &a) { return x > a.x; }
inline bool operator >= (const modint &a) { return x >= a.x; }
};
typedef modint<MOD> mint;
inline mint ksm(mint a, int b) {
mint ret = 1;
for(; b; b >>= 1, a = a * a ) if(b & 1) ret = ret * a ;
return ret;
}
const int N = 2e5 + 10;
mint fact[N + 1], infact[N + 1], inv[N + 1];
void init() {
fact[0] = 1; for(int i = 1; i <= N; ++ i ) { fact[i] = fact[i - 1] * i; }
infact[N] = ksm(fact[N], MOD - 2); for(int i = N - 1; i >= 0; -- i ) infact[i] = infact[i + 1] * (i + 1);
inv[0] = inv[1] = 1; for(int i = 2; i <= N; ++ i) inv[i] = inv[MOD % i] * (MOD - MOD / i);
}
封装线段树
int a[100010];
struct segment_tree {
struct tree {int tl, tr, val, tag;} t[M << 2];
#define l(x) t[(x)].tl
#define r(x) t[(x)].tr
#define len(x) (r(x) - l(x) + 1)
#define val(x) t[(x)].val
#define tag(x) t[(x)].tag
#define lson k << 1
#define rson k << 1 | 1
void pushup(int k)
{val(k)=val(lson)+val(rson);}
void pushdown(int k)
{val(lson) += tag(k) * len(lson), val(rson) += tag(k)*len(rson);
tag(lson) += tag(k), tag(rson) += tag(k); tag(k) = 0;}
void build(int k, int l, int r) {
l(k) = l, r(k) = r;
if(l == r) {val(k) = a[l]; return;}
int Mid = (l + r) >> 1;
build(lson,l,Mid);
build(rson, Mid + 1, r);
pushup(k);
}
void update(int k, int l, int r, int z) {
if(l(k) >= l && r(k) <= r) {val(k) += z*len(k), tag(k) += z; return;}
if(l(k) > r || r(k) < l)return;
pushdown(k);
update(lson, l, r, z); update(rson, l, r, z);
pushup(k);
}
int query(int k, int l, int r) {
if(l(k) >= l && r(k) <= r) return val(k);
if(l(k) > r || r(k) < l) return 0;
pushdown(k);
return query(lson, l, r) + query(rson, l, r);
}
}T;
最大子段和 线段树
int w[N];
struct segment {
struct node {int l, r; int lmax, rmax, tmax, sum; } tr[N << 2];
#define lson (u << 1)
#define rson (u << 1 | 1)
#define Mid (l + r) / 2
#define mid (tr[u].l + tr[u].r) / 2
void pushup(node &u, node &l, node &r) {
u.lmax = max(l.lmax, l.sum + r.lmax);
u.rmax = max(r.rmax, r.sum + l.rmax);
u.sum = l.sum + r.sum;
u.tmax = max(max(l.tmax, r.tmax), l.rmax + r.lmax);
}
void pushup (int u) {
pushup(tr[u], tr[lson], tr[rson]);
}
void build(int u, int l, int r) {
if(l == r) {
tr[u] = {l, r, w[l], w[l], w[l], w[l]};
} else {
tr[u] = {l, r};
build(lson, l, Mid), build(rson, Mid + 1, r);
pushup(u);
}
}
void modify(int u, int idx, int val) {
if(tr[u].l >= idx && tr[u].r <= idx) {
tr[u] = {idx, idx, val, val, val, val};
} else if(tr[u].l > idx || tr[u].r < idx) {
return ;
} else {
modify(lson, idx, val);
modify(rson, idx, val);
pushup(u);
}
}
node query(int u, int l, int r) {
if(tr[u].l >= l && tr[u].r <= r) {
return tr[u];
} else if(r <= mid) {
return query(lson, l, r);
} else if(l > mid) {
return query(rson, l, r);
} else {
node ans;
node left = query(lson, l, r);
node right = query(rson, l, r);
pushup(ans, left, right);
return ans;
}
}
}T;
手写 \(hash\) 函数
- 第一种
struct splitmix64 {
size_t operator()(size_t x) const {
static const size_t fixed = chrono::steady_clock::now().time_since_epoch().count();
x += 0x9e3779b97f4a7c15 + fixed;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
};
unordered_map<int, int, splitmix64> mp;
- 第二种
struct Hash {
static uint64_t splitmix64(uint64_t x) {
// http://xorshift.di.unimi.it/splitmix64.c
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);
}
};
trie 树
// by 绒绒 http://oj.daimayuan.top/submission/135434
struct Trie {
int c[N][26], tot, v[N];
void init() {
while (tot) {
v[tot] = 0;
memset(c[tot], 0, sizeof(c[tot]));
--tot;
}
memset(c[0], 0, sizeof(c[0]));
v[0] = 0;
}
void insert(char s[], int len) {
int now = 0;
for (int i = 0; i < len; ++i) {
int to = s[i] - 'a';
if (!c[now][to])c[now][to] = ++tot;
now = c[now][to];
}
v[now] = 1;
}
bool query(char s[], int len) {
int now = 0;
for (int i = len - 1; ~i; --i) {
int to = s[i] - 'a';
if (!c[now][to])return 0;
now = c[now][to];
}
return v[now];
}
}A;
01 trie
// by 严格鸽 https://www.zhihu.com/people/yan-ge-ge-32-1
void init()
{
nxt[0][0] = nxt[0][1] = 0;
cnt = 1;
}
void add(int n)
{
int cur = 0;
for (int i = MAXBIT; i >= 0; --i)
{
int bit = (n >> i) & 1;
if (!nxt[cur][bit]) {
nxt[cnt][0] = nxt[cnt][1] = 0;
nxt[cur][bit] = cnt++;
}
cur = nxt[cur][bit];
}
val[cur] = n;
}
debug
namespace debugger {
#ifdef DEBUG
template <typename T>
void __print_var(string_view name, const T & x) { std::cerr << name << " = " << x; }
void __print_var(string_view name, const string & x) { std::cerr << name << " = \"" << x << "\""; }
void __print_var(string_view name, const char & x) { std::cerr << name << " = \'" << x << "\'"; }
template <typename T>
void __print_var(string_view name, const vector<T>& x) {
std::cerr << name << " = ";
bool is_first = true;
for (auto & ele : x) std::cerr << (is_first ? (is_first = false, "[") : ", ") << ele;
std::cerr << "]";
}
template <typename T>
void __print_var(string_view name, const set<T>& x) {
std::cerr << name << " = ";
bool is_first = true;
for (auto & ele : x) std::cerr << (is_first ? (is_first = false, "{") : ", ") << ele;
std::cerr << "}";
}
template <typename K, typename V>
void __print_var(string_view name, const map<K, V>& x) {
std::cerr << name << " = ";
bool is_first = true;
for (auto & [k, v] : x) std::cerr << (is_first ? (is_first = false, "{") : ", ") << "(" << k << ": " << v << ")";
std::cerr << "}";
}
template <typename T>
void __log(string_view name, const T & x) {
__print_var(name, x); std::cerr << '\n';
}
template <typename T, typename... Ts>
void __log(string_view name, const T & x, const Ts&... others) {
size_t pos = name.find(',');
__print_var(name.substr(0, pos), x); std::cerr << ", ";
__log(name.substr(pos + 1), others...);
}
#define LOG(args...)\
{ std::cerr << "line " << __LINE__ << ": " << __func__ << "(): ";\
__log(#args, ##args); }
#else
#define LOG(...)
#endif
}
using namespace debugger;
矩阵(方阵)快速幂
struct mat {
int n; vector<vector<long long> > a;
mat() {};
mat(int _n) : n(_n){
a.resize(n + 1); a[0].resize(n + 1);
for(int i = 1; i <= n; i ++ ) {
a[i].resize(n + 1);
a[i][i] = 1;
}
};
};
mat operator * (mat T1, mat T2) {
mat ret(T1.n);
for(int i = 1; i <= T1.n; i ++ ) {
for(int j = 1; j <= T1.n; j ++ ) {
ll &res = ret.a[i][j];
res = 0;
for(int k = 1; k <= T1.n; k ++ ) {
res = (res + T1.a[i][k] * T2.a[k][j]) % p;
}
}
}
return ret;
}
mat ksm(mat x, ll k) {
mat ret(x.n);
while(k) {
if(k & 1) ret = ret * x;
k >>= 1;
x = x * x;
}
return ret;
}
字符串哈希
//https://www.acwing.com/problem/content/843/
#include <bits/stdc++.h>
using namespace std;
using ull = unsigned long long;
using Hash = pair<ull, ull>;
//如果卡常就将重载的 % mod.first %mod.second 删了,但是自然溢出可能会被卡..
constexpr Hash mod = {1000000069, 1000000067};
Hash operator*(const Hash &a, const Hash &b) {
return {a.first * b.first % mod.first, a.second * b.second % mod.second};
}
Hash operator+(const Hash &a, const Hash &b) {
return {(a.first + b.first) % mod.first, (a.second + b.second) % mod.second};
}
Hash operator-(const Hash &a, const Hash &b) {
return {(a.first - b.first + mod.first) % mod.first, (a.second - b.second + mod.second) % mod.second};
}
Hash operator*(const Hash &a, const ull &b) {
return {a.first * b % mod.first, a.second * b % mod.second};
}
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
// Hash base = {rng(), rng()};
Hash base = {rng() % mod.first, rng() % mod.second};
int n, m; cin >> n >> m;
string s; cin >> s;
vector<Hash> hash(n + 1);
hash[0] = {1, 1};
for (int i = 1; i <= n; i++) hash[i] = hash[i - 1] * base;
vector<Hash> a(n + 1);
a[0] = {1, 1};
for(int i = 1; i <= n; i ++ ) {
a[i] = a[i - 1] * base + hash[0] * s[i - 1];
}
auto get = [&] (int l, int r) {
return a[r] - a[l - 1] * hash[r - l + 1];
};
while(m -- ) {
int l1, r1, l2, r2; cin >> l1 >> r1 >> l2 >> r2;
if(get(l1, r1) == get(l2, r2)) cout << "Yes\n";
else cout << "No\n";
}
return 0;
}
马拉车
// https://www.acwing.com/problem/content/description/141/
#include <bits/stdc++.h>
using namespace std;
constexpr int N = 2000010;
int n, m, Case;
char s[N], str[N];
int p[N];
int manacher() {
int rt = 0, mid = 0;
int res = 0;
for(int i = 1; i <= m; i ++ ) {
p[i] = i < rt ? min(p[2 * mid - i], rt - i) : 1;
while(str[i + p[i]] == str[i - p[i]]) ++ p[i];
if(i + p[i] > rt) {
rt = i + p[i];
mid = i;
}
res = max(res, p[i] - 1);
}
return res;
}
int main() {
str[0] = '!', str[1] = '#';
while(scanf("%s", s), s[0] != 'E') {
n = strlen(s);
for(int i = 0; i < n; i ++ ) {
str[i * 2 + 2] = s[i];
str[i * 2 + 3] = '#';
}
m = n * 2 + 1;
str[m + 1] = '@';
printf("Case %d: %d\n", ++ Case, manacher());
}
return 0;
}
int128
#include <bits/stdc++.h>
using namespace std;
inline __int128 read()
{
__int128 x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void write(__int128 x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
write(x/10);
putchar(x%10+'0');
}
int main()
{
__int128 a = read();
write(a);
return 0;
}