字符串
Trie
01Trie
template<int BIT = 31>
class C_Trie
{
private:
int root, cnt;
vector<int>siz;
vector<vector<int>>trie;
public:
void Init(int sigma_n)
{
sigma_n *= BIT;
cnt = -1; root = ++cnt;
siz.assign(sigma_n + 1, 0);
trie.assign(sigma_n + 1, vector<int>(2, -1));
}
void Insert(int val)
{
int cur = root; siz[cur]++;
for (int i = BIT - 1; i >= 0; --i)
{
int bit = (val >> i) & 1;
if (trie[cur][bit] == -1)
{
trie[cur][bit] = ++cnt;
}
siz[cur = trie[cur][bit]]++;
}
}
int Query(int val)
{
int cur = root;
for (int i = BIT - 1; i >= 0; --i)
{
int bit = (val >> i) & 1;
if (trie[cur][bit] == -1)
{
return 0;
}
cur = trie[cur][bit];
}
return siz[cur];
}
int MaxXOR(int val)
{
int res = 0, cur = root;
for (int i = BIT - 1; i >= 0; --i)
{
int bit = ((val >> i) & 1) ^ 1;
if (trie[cur][bit] == -1)bit ^= 1;
else res += 1 << i; cur = trie[cur][bit];
}
return res;
}
};
字符Trie
template<int ASCII = 128>
class C_Trie
{
private:
int root, cnt;
vector<int>siz;
vector<vector<int>>trie;
public:
void Init(int sigma_s)
{
cnt = -1; root = ++cnt;
siz.assign(sigma_s + 1, 0);
trie.assign(sigma_s + 1, vector<int>(ASCII, -1));
}
void Insert(const string& str)
{
int cur = root; siz[cur]++;
for (int i = 0; i < str.size(); ++i)
{
if (trie[cur][str[i]] == -1)
{
trie[cur][str[i]] = ++cnt;
}
siz[cur = trie[cur][str[i]]]++;
}
}
int Query(const string& str)
{
int cur = root;
for (int i = 0; i < str.size(); ++i)
{
if (trie[cur][str[i]] == -1)
{
return 0;
}
cur = trie[cur][str[i]];
}
return siz[cur];
}
};
KMP
class C_KMP
{
private:
string pattern;
vector<int>border;
public:
void Init(const string& pattern)
{
this->pattern = pattern;
border.assign(pattern.size(), 0);
for (int i = 1, j = border[i - 1]; i < pattern.size(); ++i)
{
while (j > 0 && pattern[i] != pattern[j])
{
j = border[j - 1];
}
if (pattern[i] == pattern[j])j++;
border[i] = j;
}
}
vector<int> Find(const string& text)
{
vector<int>pos;
for (int i = 0, j = 0; i < text.size(); ++i)
{
while (j > 0 && text[i] != pattern[j])
{
j = border[j - 1];
}
if (text[i] == pattern[j])j++;
if (j == pattern.size())
{
pos.push_back(i - j + 1);
j = border[j - 1];
}
}
return pos;
}
int operator[](int idx)
{
return border[idx];
}
};
Hash
单Hash
class C_Hash
{
private:
static const lnt MOD = 998244353;
/*====================*/
vector<lnt>powbase, invbase, sumhash;
public:
void Init(const string& str, lnt base = 233)
{
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] = powbase[i - 1] * base % MOD;
}
base = Pow(base % MOD, MOD - 2, MOD);
for (int i = 0; i < str.size(); ++i)
{
if (i == 0)invbase[i] = 1;
else invbase[i] = invbase[i - 1] * base % MOD;
}
/*====================*/
for (int i = 0; i < str.size(); ++i)
{
if (i == 0)sumhash[i] = str[i] * powbase[i] % MOD;
else sumhash[i] = (sumhash[i - 1] + str[i] * powbase[i]) % MOD;
}
}
lnt operator()(int l, int r)
{
return (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, lnt base1 = 233, lnt base2 = 19260817)
{
Hash1.Init(str, base1), Hash2.Init(str, base2);
}
pair<lnt, lnt> operator()(int l, int r)
{
return { Hash1(l,r),Hash2(l,r) };
}
};
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();
}