QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#192422 | #7512. Almost Prefix Concatenation | ucup-team1198# | RE | 6ms | 7656kb | C++20 | 3.1kb | 2023-09-30 14:30:06 | 2023-09-30 14:30:06 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int, int>
#define ld long double
#define all(a) (a).begin(), (a).end()
const int MOD = 998244353;
int add(int a, int b) {
if (a + b < MOD)
return a + b;
return a + b - MOD;
}
int sub(int a, int b) {
if (a >= b)
return a - b;
return a + MOD - b;
}
int mul(int a, int b) {
return a * 1ll * b % MOD;
}
struct fenwick{
vector<int> vals;
fenwick(int n): vals(n) {}
void upd(int i, int x) {
for (; i < vals.size(); i = (i | (i + 1)))
vals[i] = add(vals[i], x);
}
int get(int i) {
int ans = 0;
for (; i >= 0; i = (i & (i + 1)) - 1)
ans = add(ans, vals[i]);
return ans;
}
int get(int l, int r) {
return sub(get(r - 1), get(l - 1));
}
};
const int MOD1 = 1e9 + 447;
const int BASE = 547;
const int MAXN = 1'000'100;
int BASEPOW[MAXN];
int mul1(int a, int b) {
return a * 1ll * b % MOD1;
}
int add1(int a, int b) {
if (a + b < MOD1)
return a + b;
return a + b - MOD1;
}
int sub1(int a, int b) {
if (a >= b)
return a - b;
return a + MOD1 - b;
}
int get_hash(vector<int>& hashes, int l, int r) {
return sub1(hashes[r], mul1(hashes[l], BASEPOW[r - l]));
}
signed main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
BASEPOW[0] = 1;
for (int i = 1; i < MAXN; ++i)
BASEPOW[i] = mul1(BASEPOW[i - 1], BASE);
string s, t;
cin >> s >> t;
vector<int> hashes1(s.size());
for (int i = 0; i < s.size(); ++i)
hashes1[i + 1] = add1(mul1(hashes1[i], BASE), s[i]);
vector<int> hashes2(t.size());
for (int i = 0; i < t.size(); ++i)
hashes2[i + 1] = add1(mul1(hashes2[i], BASE), t[i]);
fenwick f_0(s.size() + 1);
fenwick f_1(s.size() + 1);
fenwick f_2(s.size() + 1);
f_0.upd(s.size(), 1);
for (int i = int(s.size()) - 1; i >= 0; --i) {
int left = 0, right = int(s.size()) - i + 1;
while (right - left > 1) {
int mid = (left + right) / 2;
if (mid <= t.size() && get_hash(hashes1, i, i + mid) == get_hash(hashes2, 0, mid))
left = mid;
else
right = mid;
}
int same_cnt = left;
if (same_cnt != int(s.size()) - i && same_cnt != t.size()) {
left = 0, right = int(s.size()) - i - same_cnt;
while (right - left > 1) {
int mid = (left + right) / 2;
if (same_cnt + 1 + mid <= t.size() && get_hash(hashes1, i + same_cnt + 1, i + same_cnt + 1 + mid) ==
get_hash(hashes2, same_cnt + 1, same_cnt + 1 + mid))
left = mid;
else
right = mid;
}
same_cnt += 1 + left;
}
int val0 = f_0.get(i, i + same_cnt + 1);
int val1 = f_1.get(i, i + same_cnt + 1);
int val2 = f_2.get(i, i + same_cnt + 1);
f_0.upd(i, val0);
f_1.upd(i, add(val0, val1));
f_2.upd(i, add(add(val0, val1), add(val1, val2)));
}
cout << f_2.get(0, 1) << '\n';
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 7656kb
input:
ababaab aba
output:
473
result:
ok 1 number(s): "473"
Test #2:
score: 0
Accepted
time: 6ms
memory: 7512kb
input:
ac ccpc
output:
5
result:
ok 1 number(s): "5"
Test #3:
score: -100
Runtime Error
input:
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq...