代码模板

目录

  • acm
  • solve
  • power
  • 并查集DSU
  • 树状数组Fenwick
  • 线段树SegmentTree
  • KMP
  • Trie(字典树)

acm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<bits/stdc++.h>
using namespace std;
using u32 = unsigned;
#define i128 __int128;
using ll = long long;
//#define int ll
using u64 = unsigned long long;
const ll inf = 1e9;
const ll INF = 1e18;

signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);


return 0;
}

solve

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include<bits/stdc++.h>
using namespace std;
using u32 = unsigned;
#define i128 __int128
using ll = long long;
//#define int ll
using u64 = unsigned long long;
const ll inf = 1e9;
const ll INF = 1e18;
void solve(){

}

signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int tt;cin>>tt;
while(tt--){
solve();
}


return 0;
}

power

1
2
3
4
5
6
7
8
9
10
11
ll power(ll x,ll y)
{
ll ret=1;
while(y)
{
if(y&1)ret=ret*x%mod;
x=x*x%mod;
y>>=1;
}
return ret;
}

并查集DSU

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
struct DSU {
std::vector<int> f, siz;

DSU() {}
DSU(int n) {
init(n);
}

void init(int n) {
f.resize(n+1);
std::iota(f.begin(), f.end(), 0);
siz.assign(n+1, 1);
}

int find(int x) {
return f[x]==x?x:f[x]=find(f[x]);
}

bool same(int x, int y) {
return find(x) == find(y);
}

bool merge(int x, int y) {
x = find(x);
y = find(y);
if (x == y) {
return false;
}
siz[x] += siz[y];
f[y] = x;
return true;
}

int size(int x) {
return siz[find(x)];
}
};

树状数组Fenwick

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
template<typename T>
struct Fenwick{
int n;
vector<T> tr;

Fenwick(int n) : n(n), tr(n + 1, 0){}

int lowbit(int x){// 找到x最低有效位
return x & -x;
}

void modify(int x, T c){// 点修
for(int i = x; i <= n; i += lowbit(i)) tr[i] += c;
}

void modify(int l, int r, T c){// 区修
modify(l, c);
if (r + 1 <= n) modify(r + 1, -c);
}

T query(int x){// 前缀和
T res = T();
for(int i = x; i; i -= lowbit(i)) res += tr[i];
return res;
}

T query(int l, int r){// 区间查询
return query(r) - query(l - 1);
}

int find_first(T sum){// 查找第一个前缀和大于或等于 sum 的下标
int ans = 0; T val = 0;
for(int i = __lg(n); i >= 0; i--){
if ((ans | (1 << i)) <= n && val + tr[ans | (1 << i)] < sum){
ans |= 1 << i;
val += tr[ans];
}
}
return ans + 1;
}

int find_last(T sum){// 查找最后一个前缀和小于或等于 sum 的下标
int ans = 0; T val = 0;
for(int i = __lg(n); i >= 0; i--){
if ((ans | (1 << i)) <= n && val + tr[ans | (1 << i)] <= sum){
ans |= 1 << i;
val += tr[ans];
}
}
return ans;
}

};
using BIT = Fenwick<int>;

线段树SegmentTree

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
template<class Info>
struct SegmentTree {
int n;
std::vector<Info> info;
SegmentTree() : n(0) {}
SegmentTree(int n_, Info v_ = Info()) {
init(n_, v_);
}
template<class T>
SegmentTree(std::vector<T> init_) {
init(init_);
}
void init(int n_, Info v_ = Info()) {
init(std::vector(n_, v_));
}
template<class T>
void init(std::vector<T> init_) {
n = init_.size();
info.assign(4 << std::__lg(n), Info());
std::function<void(int, int, int)> build = [&](int p, int l, int r) {
if (r - l == 1) {
info[p] = init_[l];
return;
}
int m = (l + r) / 2;
build(2 * p, l, m);
build(2 * p + 1, m, r);
pull(p);
};
build(1, 0, n);
}
void pull(int p) {
info[p] = info[2 * p] + info[2 * p + 1];
}
void modify(int p, int l, int r, int x, const Info &v) {
if (r - l == 1) {
info[p] = v;
return;
}
int m = (l + r) / 2;
if (x < m) {
modify(2 * p, l, m, x, v);
} else {
modify(2 * p + 1, m, r, x, v);
}
pull(p);
}
void modify(int p, const Info &v) {
modify(1, 0, n, p, v);
}
Info rangeQuery(int p, int l, int r, int x, int y) {
if (l >= y || r <= x) {
return Info();
}
if (l >= x && r <= y) {
return info[p];
}
int m = (l + r) / 2;
return rangeQuery(2 * p, l, m, x, y) + rangeQuery(2 * p + 1, m, r, x, y);
}
Info rangeQuery(int l, int r) {
return rangeQuery(1, 0, n, l, r);
}
template<class F>
int findFirst(int p, int l, int r, int x, int y, F pred) {
if (l >= y || r <= x || !pred(info[p])) {
return -1;
}
if (r - l == 1) {
return l;
}
int m = (l + r) / 2;
int res = findFirst(2 * p, l, m, x, y, pred);
if (res == -1) {
res = findFirst(2 * p + 1, m, r, x, y, pred);
}
return res;
}
template<class F>
int findFirst(int l, int r, F pred) {
return findFirst(1, 0, n, l, r, pred);
}
template<class F>
int findLast(int p, int l, int r, int x, int y, F pred) {
if (l >= y || r <= x || !pred(info[p])) {
return -1;
}
if (r - l == 1) {
return l;
}
int m = (l + r) / 2;
int res = findLast(2 * p + 1, m, r, x, y, pred);
if (res == -1) {
res = findLast(2 * p, l, m, x, y, pred);
}
return res;
}
template<class F>
int findLast(int l, int r, F pred) {
return findLast(1, 0, n, l, r, pred);
}
};
struct Info {
int cnt = 0;
i64 sum = 0;
i64 ans = 0;
};
Info operator+(Info a, Info b) {
Info c;
c.cnt = a.cnt + b.cnt;
c.sum = a.sum + b.sum;
c.ans = a.ans + b.ans + a.cnt * b.sum - a.sum * b.cnt;
return c;
}

KMP

https://www.luogu.com.cn/record/199226881

P3375 【模板】KMP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include<bits/stdc++.h>
using namespace std;
using u32 = unsigned;
#define i128 __int128;
using ll = long long;
//#define int ll
using u64 = unsigned long long;
const ll inf = 1e9;
const ll INF = 1e18;
const int N=1e6+10;
int ne[N];
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
string s1,s2;
cin>>s1>>s2;
int n=s1.size(),m=s2.size();
for(int i=1,j=0;i<m;i++)
{
while(j&&s2[i]!=s2[j])j=ne[j];
if(s2[i]==s2[j])j++;
ne[i+1]=j;
}
for(int i=0,j=0;i<n;i++)
{
while(j&&s1[i]!=s2[j])j=ne[j];
if(s1[i]==s2[j])j++;
if(j==m)
{
cout<<i-m+1+1<<'\n';
}
}
for(int i=1;i<=m;i++)
{
cout<<ne[i]<<" \n"[i==m];
}

return 0;
}

字典树

P8306 【模板】字典树

https://www.luogu.com.cn/problem/P8306

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include<bits/stdc++.h>
using namespace std;
using u32 = unsigned;
#define i128 __int128
using ll = long long;
//#define int ll
using u64 = unsigned long long;
const ll inf = 1e9;
const ll INF = 1e18;
const int N=3e6+10;//这个N是最多有的字符个数
int ne[N][70];//第一维其中每一个数就代表了一个节点
int cnt[N];
int dix=0;
int getnum(char ch)
{
int ret;
if(isupper(ch))ret=ch-'A';
else if(islower(ch))ret=ch-'a'+26;
else ret=ch-'0'+52;
return ret;
}
void insert(string &s)
{
int p=0;
for(int i=0;i<s.size();i++)
{
int shu=getnum(s[i]);
if(!ne[p][shu])ne[p][shu]=++dix;
p=ne[p][shu];
++cnt[p];
}
}

int query(string &s)
{
int p=0;
for(int i=0;i<s.size();i++)
{
int shu=getnum(s[i]);
if(!ne[p][shu])return 0;
p=ne[p][shu];
}
return cnt[p];
}


void solve(){
// 记得每一次重置数组并将dix=0
for(int i=0;i<=dix;i++)
{
for(int j=0;j<70;j++)ne[i][j]=0;
}
for(int i=0;i<=dix;i++)cnt[i]=0;
dix=0;
int n,q;
cin>>n>>q;
for(int i=1;i<=n;i++)
{
string s;
cin>>s;
insert(s);
}
for(int i=1;i<=q;i++)
{
string s;
cin>>s;
cout<<query(s)<<'\n';
}
}

signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int tt;cin>>tt;
while(tt--){
solve();
}


return 0;
}