QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#538253 | #7748. Karshilov's Matching Problem II | longyin | WA | 619ms | 27520kb | C++20 | 3.3kb | 2024-08-31 09:36:04 | 2024-08-31 09:36:04 |
Judging History
answer
#include <bits/stdc++.h>
#define endl "\n"
using namespace std;
using ll = long long;
const ll INF = 1e18;
const int N = 5e5 + 5;
#define lc k << 1
#define rc k << 1 | 1
struct SegmentTree {
int l, r;
ll mx;
};
SegmentTree tree[N * 4];
void build(int k, int l, int r) { // 创建线段树 k表示tree数组下标, 表示区间[l, r]
tree[k].l = l;
tree[k].r = r;
if (l == r) {
tree[k].mx = -INF;
return;
}
int mid = (l + r) / 2;
build(lc, l, mid);
build(rc, mid + 1, r);
tree[k].mx = max(tree[lc].mx, tree[rc].mx);
}
void update(int k, int i, int v) { // 单点修改, 将arr[i] 修改为 v
int l = tree[k].l;
int r = tree[k].r;
if (l == r) {
tree[k].mx = v;
return;
}
int mid = (l + r) / 2;
if (i <= mid)
update(lc, i, v);
else
update(rc, i, v);
tree[k].mx = max(tree[lc].mx, tree[rc].mx);
}
ll query(int k, int l, int r) { // 区间覆盖法, 查询区间[l, r]的最值
if (tree[k].l >= l && tree[k].r <= r)
return tree[k].mx;
int mid = (tree[k].l + tree[k].r) / 2;
ll ans = -INF;
if (l <= mid)
ans = max(ans, query(lc, l, r));
if (r > mid)
ans = max(ans, query(rc, l, r));
return ans;
}
int z[N]; // 字符串 S 的子串[i, n - 1]与原串的 [最长公共前缀长度]
void getZ(const string& s) {
z[0] = s.size();
for (int i = 1, l = 0, r = 0; i < s.size(); i++) {
if (i <= r && z[i - l] < r - i + 1) {
z[i] = z[i - l];
}
else {
z[i] = max(0, r - i + 1);
while (i + z[i] < s.size() && s[z[i]] == s[i + z[i]]) {
z[i]++;
}
}
if (i + z[i] - 1 > r) {
l = i;
r = i + z[i] - 1;
}
}
}
int pi[N]; // 子串[0, i]中前缀与后缀[最长公共长度]
ll pre[N];
void getPi(const string& s){
pi[0] = 0;
for(int i = 1, j = 0; i < s.size(); i++){
while(j && s[i] != s[j])
j = pi[j - 1];
if(s[i] == s[j])
j++;
pi[i] = j;
pre[i + 1] += pre[j];
}
}
int w[N];
ll sw[N];
ll sum[N];
int main() {
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n, m;
cin >> n >> m;
string s, t;
cin >> s >> t;
for (int i = 1; i <= n; i++) {
cin >> w[i];
pre[i] = w[i];
sw[i] = sw[i - 1] + w[i];
}
getZ(s + "#" + t);
getPi(s);
for (int i = 1; i <= n; i++) {
pre[i] += pre[i - 1];
}
for (int i = 1; i <= n; i++) {
sum[i] = sum[i - 1] + sw[z[n + i]];
}
build(1, 1, n);
for (int i = 1; i <= n; i++) {
update(1, i, max(z[n + i] + i - 1, i));
}
while (m--) {
int l, r;
cin >> l >> r;
int cur = r;
int left = l, right = r;
while (left <= right) {
int mid = left + (right - left) / 2;
if (query(1, l, mid) >= r) {
cur = mid;
right = mid - 1;
}
else {
left = mid + 1;
}
}
cout << sum[cur - 1] - sum[l - 1] + pre[r + 1 - cur] << endl;
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 2ms
memory: 13836kb
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: 2ms
memory: 11812kb
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
Wrong Answer
time: 619ms
memory: 27520kb
input:
150000 150000 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...
output:
108147037823514 221878585246974 455339807727642 440286198422821 148115747906237 88695249853257 351159618462315 58850354020997 65824434822005 270158033672354 197732558443069 298193894693053 239511187032650 28139154231325 408380171835227 268053430937402 32417121185965 104813548228675 44074926058619 78...
result:
wrong answer 193rd lines differ - expected: '355571725239632', found: '355571735698367'