QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#538253#7748. Karshilov's Matching Problem IIlongyinWA 619ms27520kbC++203.3kb2024-08-31 09:36:042024-08-31 09:36:04

Judging History

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

  • [2024-08-31 09:36:04]
  • 评测
  • 测评结果:WA
  • 用时:619ms
  • 内存:27520kb
  • [2024-08-31 09:36:04]
  • 提交

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;
}

详细

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'