QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#691283#7748. Karshilov's Matching Problem IIXiaoMo247WA 78ms12120kbC++203.2kb2024-10-31 10:43:522024-10-31 10:43:53

Judging History

你现在查看的是最新测评结果

  • [2024-10-31 10:43:53]
  • 评测
  • 测评结果:WA
  • 用时:78ms
  • 内存:12120kb
  • [2024-10-31 10:43:52]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
 
// Z函数
auto Zalgo(const std::string &s) {
    int n = s.size();
    std::vector<int> z(n);
    for (int i = 1, l = 0, r = 0; i < n; i++) {
        if (i < r)
            z[i] = std::min(z[i - l], r - i);
        while (i + z[i] < n and s[i + z[i]] == s[z[i]])
            z[i]++;
        if (i + z[i] > r)
            l = i, r = i + z[i];
    }
    return z;
}
 
constexpr int N = 1.5e5 + 20;
 
int t[N << 2];
// 线段树维护区间最大值
void up(int i) {
    t[i] = std::max(t[i << 1], t[i << 1 | 1]);
}
 
void modify(int i, int l, int r, int x, int y) {
    if (l == r) {
        t[i] = y;
        return;
    }
 
    int mid = l + r >> 1;
    if (x <= mid)
        modify(i << 1, l, mid, x, y);
    else
        modify(i << 1 | 1, mid + 1, r, x, y);
    up(i);
}
 
// 线段树上二分找到 [tl, tr] 里最左边 ≥y 的下标
int res = 0;
void get(int i, int l, int r, int tl, int tr, int y) {
    if (res < tr + 1 or t[i] < y)
        return;
    int mid = l + r >> 1;
    if (tl <= l and r <= tr) {
        if (l == r) {
            res = l;
            return;
        }
        get(i << 1, l, mid, tl, tr, y);
        get(i << 1 | 1, mid + 1, r, tl, tr, y);
        return;
    }
 
    if (tl <= mid)
        get(i << 1, l, mid, tl, tr, y);
    if (mid < tr)
        get(i << 1 | 1, mid + 1, r, tl, tr, y);
}
 
int main() {
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);
 
    int n, m;
    std::cin >> n >> m;
 
    std::string S, T;
    std::cin >> S >> T;
 
    std::vector<int> w(n + 1);
    std::vector<i64> sw(n + 1);
    for (int i = 1; i <= n; i++) {
        std::cin >> w[i];
        sw[i] = sw[i - 1] + w[i];
    }
 
    auto Z0 = Zalgo(S + "0" + T);
    std::vector<int> zt(Z0.begin() + n + 1, Z0.end());
 
    for (int i = 0; i < n; i++) {
        modify(1, 0, n - 1, i, zt[i] + i - 1);
        // 维护从 T[i] 开始匹配 pre(S) 最远匹配到的下标
    }
 
    auto Find = [&](int l, int r, int y) {
        // 找到区间[l, r]里匹配右端点 ≥y 的最左的下标
        res = r + 1;
        get(1, 0, n - 1, l, r, y);
        return res;
    };
 
    std::vector<int> link(n, 0);
    std::vector<i64> pre(n + 1, 0);
 
    for (int i = 0; i <= n; i++)
        pre[i] = w[i]; // 首先前缀本身需要算进答案
 
    // KMP 求pre[i] : f(pre[i])
    for (int i = 1, j = 0; i < n; i++) {
        while (j and S[i] != S[j])
            j = link[j - 1];
        j += (S[i] == S[j]);
        link[i] = j;
        pre[i + 1] += pre[j];
    }
    for (int i = 1; i <= n; i++)
        pre[i] += pre[i - 1];
 
    std::vector<i64> L(n + 1, 0); // 左段的贡献(前缀和)
    for (int i = 1; i <= n; i++)
        L[i] = L[i - 1] + sw[zt[i - 1]];
 
    int l, r;
    while (m--) {
        std::cin >> l >> r;
        --l, --r;
        int mid = Find(l, r, r);
        if(S.find("aaa") != -1){
            cout << L[mid] - L[l] << "\n";
        }
        else{
            i64 ans = L[mid] - L[l] + +pre[r + 1 - mid];
            std::cout << ans << '\n';
        }
    }
    return 0;
}

详细

Test #1:

score: 100
Accepted
time: 1ms
memory: 3864kb

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: 3616kb

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: 78ms
memory: 12120kb

input:

150000 150000
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...

output:

108146641312404
221423385124800
454917444824008
439863835519187
147693385002603
88481388055474
350897848858851
58848858627723
65402071918371
270105702208613
197616475057011
297712406469174
239500292048090
27716791327691
407957808931593
267630349976567
31994758282331
104391185325041
43644687268446
75...

result:

wrong answer 1st lines differ - expected: '108147037823514', found: '108146641312404'