QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#193594 | #7512. Almost Prefix Concatenation | ucup-team228# | WA | 5ms | 27288kb | C++20 | 5.9kb | 2023-09-30 17:32:32 | 2023-09-30 17:32:33 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<int mod>
class Modular {
public:
int val;
Modular() : val(0) {}
Modular(int new_val) : val(new_val) {}
// Modular(long long new_val) : val(new_val % mod) {} // AFFECTS OPERATOR* (because it has one more %)
friend Modular operator+(const Modular& a, const Modular& b) {
if (a.val + b.val >= mod) return a.val + b.val - mod;
else return a.val + b.val;
}
friend Modular operator-(const Modular& a, const Modular& b) {
if (a.val - b.val < 0) return a.val - b.val + mod;
else return a.val - b.val;
}
friend Modular operator*(const Modular& a, const Modular& b) {
return 1ll * a.val * b.val % mod;
}
friend Modular binpow(Modular a, long long n) {
Modular res = 1;
for (; n; n >>= 1) {
if (n & 1) res *= a;
a *= a;
}
return res;
}
/* ALTERNATIVE INVERSE FUNCTION USING EXTENDED EUCLIDEAN ALGORITHM
friend void gcd(int a, int b, Modular& x, Modular& y) {
if (a == 0) {
x = Modular(0);
y = Modular(1);
return;
}
Modular x1, y1;
gcd(b % a, a, x1, y1);
x = y1 - (b / a) * x1;
y = x1;
}
friend Modular inv(const Modular& a) {
Modular x, y;
gcd(a.val, mod, x, y);
return x;
}
*/
friend Modular inv(const Modular& a) {
return binpow(a, mod - 2);
}
Modular operator/(const Modular& ot) const {
return *this * inv(ot);
}
Modular& operator++() {
if (val + 1 == mod) val = 0;
else ++val;
return *this;
}
Modular operator++(int) {
Modular tmp = *this;
++(*this);
return tmp;
}
Modular operator+() const {
return *this;
}
Modular operator-() const {
return 0 - *this;
}
Modular& operator+=(const Modular& ot) {
return *this = *this + ot;
}
Modular& operator-=(const Modular& ot) {
return *this = *this - ot;
}
Modular& operator*=(const Modular& ot) {
return *this = *this * ot;
}
Modular& operator/=(const Modular& ot) {
return *this = *this / ot;
}
bool operator==(const Modular& ot) const {
return val == ot.val;
}
bool operator!=(const Modular& ot) const {
return val != ot.val;
}
bool operator<(const Modular& ot) const {
return val < ot.val;
}
bool operator>(const Modular& ot) const {
return val > ot.val;
}
explicit operator int() const {
return val;
}
};
template<int mod>
istream& operator>>(istream& istr, Modular<mod>& x) {
return istr >> x.val;
}
template<int mod>
ostream& operator<<(ostream& ostr, const Modular<mod>& x) {
return ostr << x.val;
}
const int mod = 998244353; // 998244353
using Mint = Modular<mod>;
template <int mod>
struct PolyHash {
int N;
std::mt19937 rnd;
Modular<mod> p = rnd() % 10000 + 1000;
vector<Modular<mod>> pw;
vector<Modular<mod>> pref;
template <typename container>
void init(const container& a) {
int n = a.size();
pw.resize(n + 1, 0);
pref.resize(n + 1, 0);
pw[0] = 1;
for (int i = 1; i <= n; i++) {
pref[i] = pref[i - 1] * p + a[i - 1];
pw[i] = pw[i - 1] * p;
}
}
Modular<mod> get(int l, int r) {
++l, ++r;
return pref[r] - pref[l - 1] * pw[r - l + 1];
}
};
const int m1 = 1000000123;
const int m2 = 1000000321;
const int m3 = 5000101;
const int m4 = 7000003;
const int m5 = 5003;
const int m6 = 6007;
const int N = 1e6 + 10;
Mint dp[3][N], suf[3][N];
PolyHash<m1> s_p, t_p;
PolyHash<m2> s_q, t_q;
bool cmp(int sl, int sr, int n, int tl, int tr, int m) {
if (sr >= n || tr >= m) {
return false;
}
return sr - sl == tr - tl && s_p.get(sl, sr) == t_p.get(tl, tr) && s_q.get(sl, sr) == t_q.get(tl, tr);
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
#ifdef LOCAL
freopen("input.txt", "r", stdin);
#endif
string s, t;
cin >> s >> t;
int n = s.size(), m = t.size();
s_p.init(s);
s_q.init(s);
t_p.init(t);
t_q.init(t);
dp[0][n] = 1;
dp[1][n] = 0;
dp[2][n] = 0;
suf[0][n] = dp[0][n];
suf[1][n] = dp[1][n];
suf[2][n] = dp[2][n];
for (int i = n - 1; i >= 0; i--) {
int x = i;
if (s[i] == t[0]) {
int lef = i, rig = n - 1;
while (lef < rig) {
int mid = (lef + rig) / 2;
if (cmp(i, mid + 1, n, 0, mid + 1 - i + 1, m)) {
lef = mid + 1;
} else {
rig = mid;
}
}
x = lef + 1;
}
int y = x;
if (x + 1 < n && s[x + 1] == t[x - i + 1]) {
int lef = x + 1, rig = n - 1;
while (lef < rig) {
int mid = (lef + rig) / 2;
if (cmp(x + 1, mid + 1, n, x - i + 1, mid + 1 - i, m)) {
lef = mid + 1;
} else {
rig = mid;
}
}
y = lef;
}
y = min(y, n - 1);
dp[0][i] = suf[0][i + 1] - suf[0][y + 2];
dp[1][i] = suf[1][i + 1] - suf[1][y + 2] + suf[0][i + 1] - suf[0][y + 2];
dp[2][i] = suf[2][i + 1] - suf[2][y + 2] + 2 * (suf[1][i + 1] - suf[1][y + 2]) + suf[0][i + 1] - suf[0][y + 2];
suf[0][i] = suf[0][i + 1] + dp[0][i];
suf[1][i] = suf[1][i + 1] + dp[1][i];
suf[2][i] = suf[2][i + 1] + dp[2][i];
}
cout << dp[2][0] << "\n";
#ifdef LOCAL
cout << "\nTime elapsed: " << double(clock()) / CLOCKS_PER_SEC << " s.\n";
#endif
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 27288kb
input:
ababaab aba
output:
473
result:
ok 1 number(s): "473"
Test #2:
score: 0
Accepted
time: 5ms
memory: 27288kb
input:
ac ccpc
output:
5
result:
ok 1 number(s): "5"
Test #3:
score: 0
Accepted
time: 0ms
memory: 27064kb
input:
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq...
output:
75038697
result:
ok 1 number(s): "75038697"
Test #4:
score: -100
Wrong Answer
time: 4ms
memory: 27068kb
input:
lvvvllvllvllvllllllllvvvllvlllvvlvlvllvlvvlvvvvlvvllllllvvlvlvvlllvvlvlvllllllvlvvvvvvlllvvvllvlvvvlvvlllvvvvvvlvlllvvvvlvvvvvlvvlvvlllvvllvvllvlvlvlvlvllllvvllvvllvlllvvvllllvvlvvllvvvvlvlvvlvvlllvvvvvvvvlvvlvlllvllvvvvllvvvlvvvvvvlvlllvllllvllllllllvvllllllvlvvlvvvlvllllvllvlvvllllllvlvvvlvlvlvvvl...
output:
73547828
result:
wrong answer 1st numbers differ - expected: '538419149', found: '73547828'