0%

第十一届中国大学生程序设计竞赛网络预选赛(CCPC Online 2025)——通配符匹配

思路讲解

难点其实就在与这个想到把

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
vector<vll> valids(SZ(seg));
FOR(i, 0, SZ(seg) - 1) {
auto [hs, len] = seg[i];
FOR(j, 0, SZ(s) - 1) {
if (len + j - 1 >= SZ(s)) {
break;
}
ll r = len + j - 1;
if (cal(hss, j, r) == hs) {
valids[i].PB(j);
}
}
if (valids[i].empty()) {
cout << 0 << "\n";
return;
}
}
// 特判没有*的情况
if (!have) {
cout << SZ(valids[0]) << "\n";
return;
}
ll ans = 0;
// *之间的这个长度是一定的
if (t.back() == '*' && t.front() == '*') {
ll on = SZ(s) - 1;
ROF(i, SZ(valids.back()) - 1, 0) {
ll p = valids.back()[i];
bool ok = true;
ll up = p;
ROF(j, SZ(seg) - 2, 0) {
ll len = seg[j][1];
auto it = upper_bound(all(valids[j]), up - len);
if (it == valids[j].begin()) {
ok = false;
break;
}
it--;
up = *it;
}
if (!ok) {
continue;
}
ll ed = p + seg.back()[1] - 1;
ans += (up - 0 + 1) * (on - ed + 1);
on = ed - 1;
}
} else if (t.back() == '*') {
ll on = SZ(s) - 1;
ROF(i, SZ(valids.back()) - 1, 0) {
ll p = valids.back()[i];
bool ok = true;
ll up = p;
ROF(j, SZ(seg) - 2, 0) {
ll len = seg[j][1];
auto it = upper_bound(all(valids[j]), up - len);
if (it == valids[j].begin()) {
ok = false;
break;
}
it--;
up = *it;
}
if (!ok) {
continue;
}
ll ed = p + seg.back()[1] - 1;
auto t = lower_bound(all(valids[0]), up) - valids[0].begin() + 1;
ans += t * (on - ed + 1);
on = ed - 1;
}
} else if (t.front() == '*') {
for (auto p : valids.back()) {
bool ok = true;
ll up = p;
ROF(j, SZ(seg) - 2, 0) {
ll len = seg[j][1];
auto it = upper_bound(all(valids[j]), up - len);
if (it == valids[j].begin()) {
ok = false;
break;
}
it--;
up = *it;
}
if (!ok) {
continue;
}
ans += up - 0 + 1;
}
} else {
for (auto p : valids.back()) {
bool ok = true;
ll up = p;
ROF(j, SZ(seg) - 2, 0) {
ll len = seg[j][1];
auto it = upper_bound(all(valids[j]), up - len);
if (it == valids[j].begin()) {
ok = false;
break;
}
it--;
up = *it;
}
if (!ok) {
continue;
}
auto t = lower_bound(all(valids[0]), up) - valids[0].begin() + 1;
ans += t;
}
}
cout << (long long)ans;

AC代码

https://qoj.ac/submission/1395803

心路历程(WA,TLE,MLE……)