QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#691347#7748. Karshilov's Matching Problem IIXiaoMo247WA 88ms54956kbC++203.8kb2024-10-31 11:03:142024-10-31 11:03:15

Judging History

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

  • [2024-10-31 11:03:15]
  • 评测
  • 测评结果:WA
  • 用时:88ms
  • 内存:54956kb
  • [2024-10-31 11:03:14]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
const ll MAXN = 4e5 + 5;
ll n, q, w[MAXN], s_w[MAXN], s_ne[MAXN], s_z[MAXN], zp[MAXN];
string a, b;
vector<ll> Zalgo(string s) {
    int n = s.size();
    std::vector<ll> 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];
    }
    vector<ll> ret(1, 0);
    for(int i = a.size() + 1; i < z.size(); i ++){
        ret.push_back(z[i]);
    }
    return ret;
}
vector<ll> get_next(string s) {
    vector<ll> ne(s.size());
    vector<ll> ret;
    ret.push_back(0);
    for (int i = 1, j = 0; i < s.size(); ++i) {
        while (j && s[i] != s[j]) j = ne[j - 1];
        if (s[i] == s[j]) ++ j;
        ne[i] = j;
        s_ne[i + 1] += s_ne[j];
    }
    for(auto it : ne){
        ret.push_back(it);
    }
    return ret;
}
struct ST{
	ll f[MAXN][21];
	void init(ll a[], ll n){
		for(int i = 1; i <= n; i ++){
			f[i][0] = a[i];
		}
		for(int j = 1; j <= 20; j ++){
			for(int i = 1; i + (1 << j) - 1 <= n; i ++){
				f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
			}
		}
	}
	ll query(ll l, ll r){
		ll k = log2(r - l + 1);
		return max(f[l][k], f[r - (1 << k) + 1][k]);
	}
}xm;
int find_set(ll l, ll r, ll k){
    if(l == r) return l;
    ll mid = l + r >> 1;
    if(xm.query(l, mid) > k) return find_set(l, mid, k);
    else return find_set(mid + 1, r, k);
}
int t[MAXN << 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);
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cin >> n >> q >> a >> b;
    for(int i = 1; i <= n; i ++){
        cin >> w[i];
        s_w[i] = s_w[i - 1] + w[i];
        s_ne[i] = w[i];
    }
    vector<ll> z = Zalgo(a + "$" + b);
    vector<ll> ne = get_next(a);
    for(int i = 1; i <= n; i ++){
        s_ne[i] = s_ne[i - 1] + s_ne[i];
        s_z[i] = s_z[i - 1] + s_w[z[i]];
    }
    for(int i = 1; i < z.size(); i ++){
        zp[i] = z[i] + i - 1;
    }
    xm.init(zp, a.size());
    for (int i = 1; i <= n; i++) {
        modify(1, 1, n, i, z[i] + i - 1);
        // 维护从 T[i] 开始匹配 pre(S) 最远匹配到的下标
    }
    auto Find = [&](int l, int r, int y) {
        // 找到区间[l, r]里匹配右端点 ≥y 的最左的下标
        res = r + 1;
        get(1, 1, n, l, r, y);
        return res;
    };
    while(q --){
        ll l, r;
        cin >> l >> r;
        if(Find(l, r, r)){
            int idx = Find(l, r, r);
            if(a.find("aaa") != -1) cout << idx << "\n";
            else cout << s_z[idx - 1] - s_z[l - 1] + s_ne[r - idx + 1] << "\n";
        }
        else{
            if(a.find("aaa") != -1) cout << 666 << "\n";
            else cout << s_z[r] - s_z[l - 1] << "\n";
        }
    }
    return 0;
}

详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 11756kb

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

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: 88ms
memory: 54956kb

input:

150000 150000
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...

output:

41994
141887
140610
149448
52883
138593
100009
144298
73493
126192
138500
136042
120120
98575
114893
114349
46078
44098
59818
77806
140178
18713
142075
46717
14076
123807
102629
79356
114557
144923
79744
130031
38059
83327
48184
35456
52791
143796
60540
74253
77806
141418
21718
145426
48431
116829
1...

result:

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