字符串
Trie
class C_Trie
{
private:
int cnt;
vector<int>siz;
vector<vector<int>>trie;
public:
void Init(int sumlen)
{
cnt = 0;siz.assign(sumlen + 1, 0);
trie.assign(sumlen + 1, vector<int>(26, -1));
}
void Insert(const string& str)
{
int cur = 0; siz[cur]++;
for (int i = 0; i < str.size(); ++i)
{
if (trie[cur][str[i] - 'a'] == -1)
{
trie[cur][str[i] - 'a'] = ++cnt;
}
siz[cur = trie[cur][str[i] - 'a']]++;
}
}
int Query(const string& str)
{
int cur = 0;
for (int i = 0; i < str.size(); ++i)
{
if (trie[cur][str[i] - 'a'] == -1)
{
return 0;
}
cur = trie[cur][str[i] - 'a'];
}
return siz[cur];
}
};
KMP
KMP(静态)
class C_KMP
{
private:
string pattern;
vector<int>lps;
public:
void Init(const string& pattern)
{
this->pattern = pattern;
lps.assign(pattern.size(), 0);
for (int i = 1, len = 0;i < pattern.size();++i)
{
while (len > 0 && pattern[i] != pattern[len])
{
len = lps[len - 1];
}
if (pattern[i] == pattern[len])len++;
lps[i] = len;
}
}
vector<int> Find(const string& text)
{
vector<int>pos;
for (int i = 0, len = 0;i < text.size();++i)
{
while (len > 0 && text[i] != pattern[len])
{
len = lps[len - 1];
}
if (text[i] == pattern[len])len++;
if (len == pattern.size())
{
pos.push_back(i - len + 1);
len = lps[len - 1];
}
}
return pos;
}
int operator[](int idx)
{
return lps[idx];
}
};
KMP(动态)
class C_KMP
{
private:
string pattern;
vector<int>lps;
public:
void PushBack(char c)
{
pattern.push_back(c);lps.push_back(0);
for (int i = max(1, int(pattern.size()) - 2), j = lps[i - 1];i < pattern.size();++i)
{
while (j > 0 && pattern[i] != pattern[j])
{
j = lps[j - 1];
}
if (pattern[i] == pattern[j])j++;
lps[i] = j;
}
}
void PopBack(void)
{
pattern.pop_back();lps.pop_back();
}
int Size(void)
{
return pattern.size();
}
int operator[](int idx)
{
return lps[idx];
}
};
KMP(自动机)
template<int SIGMA = 26>
class C_KMPAM
{
private:
string pattern;
vector<int>lps;
vector<vector<int>>trans;
public:
void Init(const string& pattern)
{
this->pattern = pattern;
lps.reserve(pattern.size());
trans.assign(pattern.size() + 1, vector<int>(26, 0));
trans[0][pattern[0] - 'A'] = 1;int lastlps = 0;
for (int i = 1;i <= pattern.size();++i)
{
lps.push_back(lastlps);
for (char c = 'A';c <= 'Z';++c)
{
trans[i][c - 'A'] = trans[lastlps][c - 'A'];
}
if (i < pattern.size())
{
trans[i][pattern[i] - 'A'] = i + 1;
lastlps = trans[lastlps][pattern[i] - 'A'];
}
}
}
vector<int> Find(const string& text)
{
vector<int>pos;int cur = 0;
for (int i = 0;i < text.size();++i)
{
cur = trans[cur][text[i] - 'A'];
if (cur == pattern.size())
{
pos.push_back(i - pattern.size() + 1);
}
}
return pos;
}
int operator[](int idx)
{
return lps[idx];
}
};
Hash
单Hash
class C_Hash
{
private:
static constexpr int MOD = 998244353;
/*====================*/
vector<int>powbase, invbase, sumhash;
public:
void Init(const string& str, int base = 131, int invb = 922042494)
{
powbase.assign(str.size(), 0);
invbase.assign(str.size(), 0);
sumhash.assign(str.size(), 0);
/*====================*/
for (int i = 0; i < str.size(); ++i)
{
if (i == 0)powbase[i] = 1;
else powbase[i] = 1ll * powbase[i - 1] * base % MOD;
}
for (int i = 0; i < str.size(); ++i)
{
if (i == 0)invbase[i] = 1;
else invbase[i] = 1ll * invbase[i - 1] * invb % MOD;
}
/*====================*/
for (int i = 0; i < str.size(); ++i)
{
if (i == 0)sumhash[i] = 1ll * str[i] * powbase[i] % MOD;
else sumhash[i] = (sumhash[i - 1] + 1ll * str[i] * powbase[i]) % MOD;
}
}
int operator()(int l, int r)
{
return 1ll * (sumhash[r] - (l > 0 ? sumhash[l - 1] : 0) + MOD) * invbase[l] % MOD;
}
};
双Hash
class C_DoubleHash
{
private:
C_Hash hash1, hash2;
public:
void Init(const string& str)
{
hash1.Init(str, 131, 922042494);
hash2.Init(str, 233, 844009174);
}
lnt operator()(int l, int r)
{
return (lnt(hash1(l, r)) << 32) | (hash2(l, r) & 0xFFFFFFFF);
}
};
Split
vector<string> Split(const string& str, char c)
{
string temp;
vector<string>res;
istringstream iss(str);
while (getline(iss, temp, c))
{
if (temp != "")
{
res.push_back(temp);
}
}
return res;
}
Z函数
vector<int> Z_Function(const string& str)
{
int n = str.size() - 1;
vector<int>z(str.size());
int l = 1, r = 1; z[1] = n;
for (int i = 2; i <= n; ++i)
{
z[i] = (i <= r ? min(z[i - l + 1], r - i + 1) : 0);
while (i + z[i] <= n && str[1 + z[i]] == str[i + z[i]])z[i]++;
if (i + z[i] - 1 > r)r = i + z[i] - 1, l = i;
}
return z;
}
表达式
获取优先级
int GetPriority(char c)
{
if (c == '*')return 0;
if (c == '+')return -1;
return -2;
}
中缀转后缀
string PostfixExpression(string str)
{
string res;
stack<char>stk;
for (auto c : str)
{
if (c == '_')
{
res.push_back(c);
}
if (c == '(' || c == ')')
{
if (c == '(')
{
stk.push('(');
}
if (c == ')')
{
while (!stk.empty() && stk.top() != '(')
{
res.push_back(stk.top()); stk.pop();
}
stk.pop();
}
}
if (c == '+' || c == '*')
{
while (!stk.empty() && GetPriority(stk.top()) >= GetPriority(c))
{
res.push_back(stk.top()); stk.pop();
}
stk.push(c);
}
}
while (!stk.empty())
{
res.push_back(stk.top()); stk.pop();
}
return res;
}
建立表达式树
struct Node
{
int val;
char tag;
Node* lch, * rch;
Node(int _val = 0, char _tag = ' ', Node* _lch = NULL, Node* _rch = NULL)
{
val = _val, tag = _tag;
lch = _lch, rch = _rch;
}
};
Node* Build(string str)
{
stack<Node*>stk;
for (auto c : str)
{
if (c == '0' || c == '1')
{
stk.push(new Node(c - '0', ' ', NULL, NULL));
}
else
{
Node* rch = stk.top(); stk.pop();
Node* lch = stk.top(); stk.pop();
stk.push(new Node(((c == '&') ? (lch->val & rch->val) : (lch->val | rch->val)), c, lch, rch));
}
}
return stk.top();
}
Manacher
vector<int> Manacher(string str)
{
do
{
string tmp(2 * str.size() + 3, '#');
tmp.front() = '+';
for (int i = 0;i < str.size();++i)
{
tmp[2 * (i + 1)] = str[i];
}
tmp.back() = '-';
str = tmp;
} while (false);
/*====================*/
int c = 0;vector<int>p(str.size(), 1);
for (int i = 1;i < str.size();++i)
{
if (i <= c + p[c] - 1)
{
p[i] = min(p[2 * c - i], c + p[c] - i);
}
while (str[i - p[i]] == str[i + p[i]])p[i]++;
if (i + p[i] - 1 > c + p[c] - 1)c = i;
}
return p;
}