QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#346237 | #7748. Karshilov's Matching Problem II | Lain | TL | 0ms | 3644kb | C++23 | 3.1kb | 2024-03-08 00:56:10 | 2024-03-08 00:56:11 |
Judging History
answer
#include "bits/stdc++.h"
using namespace std;
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
// Source: Me
// Tested on: CF 1575 H
namespace KMP {
char MIN_CHAR = 'a';
int ALPHABET = 26;
// Finds longest prefix of [0..i] such that it is also a suffix of [0..i]
vector<int> prefix_function(string s) {
int n = (int)s.length();
vector<int> pi(n);
for (int i = 1; i < n; i++) {
int j = pi[i - 1];
while (j > 0 && s[i] != s[j]) j = pi[j - 1];
if (s[i] == s[j]) j++;
pi[i] = j;
}
return pi;
}
// KMP match finding algorithm
vector<int> find_matches(const string& s, const string& pat) {
vector<int> p = prefix_function(pat + '\0' + s), res;
for (int i = (int)p.size() - (int)s.size(); i < p.size(); i++)
if (p[i] == pat.size()) res.push_back(i - 2 * pat.size());
return res;
}
// Builds KMP automaton aut
// aut[p][c] = transition from pi when adding character c
vector<vector<int>> build_automaton(string s) {
s += '\0';
int n = s.size();
vector<int> pi = prefix_function(s);
vector<vector<int>> aut(n, vector<int>(ALPHABET));
for (int i = 0; i < n; i++) {
for (int c = 0; c < ALPHABET; c++) {
if (i > 0 && MIN_CHAR + c != s[i])
aut[i][c] = aut[pi[i - 1]][c];
else
aut[i][c] = i + (MIN_CHAR + c == s[i]);
}
}
return aut;
}
}; // namespace KMP
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
const int B = 400;
int n, q;
cin >> n >> q;
string s, t;
cin >> s >> t;
// Handle w
vector<int> w(n+1);
rep(i, 1, n+1) cin >> w[i];
auto pi = KMP::prefix_function(s);
rep(i, 1, n+1) {
w[i] += w[pi[i-1]];
}
/* for (auto& x : w) cout << x << " "; */
/* cout << '\n'; */
// Generate the sqrt decomposition
auto aut = KMP::build_automaton(s);
using P = pair<int64_t, int>;
vector<vector<P>> blocks;
for (int i = 0; i*B < n; i++) {
vector<P> curr(sz(s) + 1);
rep(j, 0, sz(s) + 1) {
curr[j].first = 0, curr[j].second = j;
}
for (int j = i*B; j < (i+1)*B && j < n; j++) {
for (auto& p : curr) {
int nxt = aut[p.second][t[j] - 'a'];
p.first += w[nxt];
p.second = nxt;
}
}
blocks.push_back(curr);
}
while(q--) {
int l, r;
cin >> l >> r;
l--, r--;
int st = l/B, en = r/B;
if (st == en) {
// start and end in same block
int curr =0;
int64_t res =0;
rep(i, l, r+1) {
curr = aut[curr][t[i] - 'a'];
res += w[curr];
}
cout << res << '\n';
continue;
}
int curr = 0;
int64_t res = 0;
rep(i, l, (st+1)*B) {
curr = aut[curr][t[i] - 'a'];
res += w[curr];
}
rep(i, st+1, en) {
res += blocks[i][curr].first;
curr = blocks[i][curr].second;
}
rep(i, en*B, r+1) {
curr = aut[curr][t[i] - 'a'];
res += w[curr];
}
cout << res << '\n';
}
}
詳細信息
Test #1:
score: 100
Accepted
time: 0ms
memory: 3600kb
input:
8 5 abbabaab aababbab 1 2 4 8 16 32 64 128 1 1 2 3 3 5 4 7 1 8
output:
1 3 3 16 38
result:
ok 5 lines
Test #2:
score: 0
Accepted
time: 0ms
memory: 3644kb
input:
15 4 heheheheehhejie heheheheheheheh 3 1 4 1 5 9 2 6 5 3 5 8 9 7 9 2 3 4 8 2 6 1 15
output:
3 13 13 174
result:
ok 4 lines
Test #3:
score: -100
Time Limit Exceeded
input:
150000 150000 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...