QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#192490 | #7512. Almost Prefix Concatenation | ucup-team1516# | WA | 1ms | 5584kb | C++20 | 7.8kb | 2023-09-30 14:39:59 | 2023-09-30 14:40:00 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define db double
#define pii pair<int,int>
#define pli pair<ll,int>
#define pil pair<int,ll>
#define pll pair<ll,ll>
#define ti3 tuple<int,int,int>
#define int128 __int128_t
#define pii128 pair<int128,int128>
const int inf = 1 << 30;
const ll linf = 1e18;
const ll mod = 998244353;
const db EPS = 1e-10;
const db pi = acos(-1);
template<class T> bool chmin(T& x, T y){
if(x > y) {
x = y;
return true;
} else return false;
}
template<class T> bool chmax(T& x, T y){
if(x < y) {
x = y;
return true;
} else return false;
}
// overload macro
#define CAT( A, B ) A ## B
#define SELECT( NAME, NUM ) CAT( NAME, NUM )
#define GET_COUNT( _1, _2, _3, _4, _5, _6 /* ad nauseam */, COUNT, ... ) COUNT
#define VA_SIZE( ... ) GET_COUNT( __VA_ARGS__, 6, 5, 4, 3, 2, 1 )
#define VA_SELECT( NAME, ... ) SELECT( NAME, VA_SIZE(__VA_ARGS__) )(__VA_ARGS__)
// rep(overload)
#define rep( ... ) VA_SELECT(rep, __VA_ARGS__)
#define rep2(i, n) for (int i = 0; i < int(n); i++)
#define rep3(i, a, b) for (int i = a; i < int(b); i++)
#define rep4(i, a, b, c) for (int i = a; i < int(b); i += c)
// repll(overload)
#define repll( ... ) VA_SELECT(repll, __VA_ARGS__)
#define repll2(i, n) for (ll i = 0; i < ll(n); i++)
#define repll3(i, a, b) for (ll i = a; i < ll(b); i++)
#define repll4(i, a, b, c) for (ll i = a; i < ll(b); i += c)
// rrep(overload)
#define rrep( ... ) VA_SELECT(rrep, __VA_ARGS__)
#define rrep2(i, n) for (int i = n - 1; i >= 0; i--)
#define rrep3(i, a, b) for (int i = b - 1; i >= a; i--)
#define rrep4(i, a, b, c) for (int i = b - 1; i >= a; i -= c)
// rrepll(overload)
#define rrepll( ... ) VA_SELECT(rrepll, __VA_ARGS__)
#define rrepll2(i, n) for (ll i = n - 1; i >= 0ll; i--)
#define rrepll3(i, a, b) for (ll i = b - 1; i >= ll(a); i--)
#define rrepll4(i, a, b, c) for (ll i = b - 1; i >= ll(a); i -= c)
// for_earh
#define fore(e, v) for (auto&& e : v)
// vector
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
template<long long mod>
struct modint{
long long num;
constexpr modint(long long x = 0) : num((x + mod) % mod) {}
constexpr modint &operator += (const modint& rhs){
num = (num + rhs.num) % mod;
return *this;
}
constexpr modint &operator -= (const modint& rhs){
num -= rhs.num;
while(num < 0) num += mod;
num %= mod;
return *this;
}
constexpr modint &operator *= (const modint& rhs){
num = num * rhs.num % mod;
return *this;
}
constexpr modint &operator /= (modint rhs){
int exp = mod - 2;
while(exp > 0){
if(exp % 2){
*this *= rhs;
}
rhs *= rhs;
exp /= 2;
}
return *this;
}
constexpr modint operator ++ (){
num = (num + 1) % mod;
return *this;
}
constexpr modint operator ++ (int n){
(void)n;
modint tmp = *this;
++(*this);
return tmp;
}
constexpr modint operator -- (){
num = (num + mod - 1) % mod;
return *this;
}
constexpr modint operator -- (int n){
(void)n;
const modint tmp = *this;
--(*this);
return tmp;
}
void modpow(ll y){
modint tmp = (*this);
(*this) = 1;
while(y > 0){
if(y % 2){
(*this) *= tmp;
}
tmp *= tmp;
y /= 2;
}
}
constexpr modint operator + (const modint& rhs) const {
return modint(*this) += rhs;
}
constexpr modint operator - (const modint& rhs) const {
return modint(*this) -= rhs;
}
constexpr modint operator * (const modint& rhs) const {
return modint(*this) *= rhs;
}
constexpr modint operator / (const modint& rhs) const {
return modint(*this) /= rhs;
}
friend ostream &operator << (ostream& lhs, const modint& rhs){
return lhs << rhs.num;
}
friend istream &operator >> (istream& lhs, modint& rhs){
lhs >> rhs.num;
return lhs;
}
};
#define mint modint<mod>
random_device rnd;
mt19937 mt(rnd());
struct rolling_hash {
private:
static inline const ll base = mt() + 2;
static const ll MASK30 = (1ll << 30) - 1;
static const ll MASK31 = (1ll << 31) - 1;
static const ll HASH_MOD = (1ll << 61) - 1;
static const ll MASK61 = HASH_MOD;
ll calc_mod(ll x) {
ll xu = x >> 61;
ll xl = x & MASK61;
ll ret = xu + xl;
if (ret >= HASH_MOD) ret -= HASH_MOD;
return ret;
}
ll calc_mul(ll a, ll b) {
ll au = a >> 31;
ll al = a & MASK31;
ll bu = b >> 31;
ll bl = b & MASK31;
ll mid = al * bu + au * bl;
ll midu = mid >> 30;
ll midl = mid & MASK30;
return calc_mod(au * bu * 2 + midu + (midl << 31) + al * bl);
}
public:
int N;
string S;
vector<ll> hash, power;
rolling_hash(){}
rolling_hash(string s) : N(s.size()), S(s), hash(N + 1), power(N + 1) {
power[0] = 1, hash[0] = S[0];
for (int i = 0; i < N; i++) {
power[i + 1] = calc_mul(power[i], base);
hash[i + 1] = calc_mod(calc_mul(hash[i], base) + s[i]);
}
}
ll get_hash(int l = 0, int r = -1) {
if (r == -1) r = N;
return calc_mod(hash[r] - calc_mul(hash[l], power[r - l]) + HASH_MOD);
}
};
mint modpow(mint x, ll y){
if(y == 0) return 1;
mint e = modpow(x, y / 2);
e = e * e;
return e * (y % 2 == 0 ? 1 : x);
}
vector<int> Z_algorithm(string S, string T = "") {
if (T == "") T = S;
S += '$';
S += T;
vector<int> Z(S.size());
Z[0] = S.size();
int i = 1, j = 0;
while(i < (int)S.size()) {
while(i + j < (int)S.size() && S[j] == S[i + j]) j++;
Z[i] = j;
if (j == 0) {
i++;
continue;
}
int k = 1;
while (k < j && k + Z[k] < j) {
Z[i + k] = Z[k];
k++;
}
i += k;
j -= k;
}
vector<int> res(T.size());
copy(Z.end() - T.size(), Z.end(), res.begin());
return res;
}
string S, T;
// cnt: i番目までの分割の仕方の通り数 val: すべての場合の分割によってできた文字列の個数の和
mint cnt[1000010], val[1000010], ans[1000010];
int main() {
cin.tie(nullptr);
ios_base::sync_with_stdio(false);
cout << fixed << setprecision(20);
cin >> S >> T;
string TS = T + "#" + S;
auto z = Z_algorithm(TS);
vector<int> sz = {z.begin() + T.size() + 1, z.end()};
rep (i, S.size()) {
sz[i] = min((int)S.size() - i, min(sz[i] + 1, (int)T.size()));
}
rolling_hash rs(S), rt(T);
rep (i, S.size()) {
ll lb = 0, ub = min(T.size() - sz[i], S.size() - (i + sz[i])) + 1;
while (ub - lb > 1) {
int mid = (ub + lb) / 2;
if (rs.get_hash(i + sz[i], i + sz[i] + mid) == rs.get_hash(sz[i], sz[i] + mid)) lb = mid;
else ub = mid;
}
sz[i] += lb;
}
cnt[0] = 1;
cnt[1] = -1;
rep (i, S.size()) {
cnt[i + 1] += cnt[i] * 2;
cnt[i + sz[i] + 1] -= cnt[i];
}
rep (i, S.size()) {
val[i + 1] += val[i] + cnt[i];
val[i + sz[i] + 1] -= val[i] + cnt[i];
val[i + 1] += val[i];
}
rep (i, S.size()) {
ans[i + 1] += ans[i] + val[i] * 2 + cnt[i];
ans[i + sz[i] + 1] -= ans[i] + val[i] * 2 + cnt[i];
ans[i + 1] += ans[i];
}
cout << ans[S.size()] << endl;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 5536kb
input:
ababaab aba
output:
473
result:
ok 1 number(s): "473"
Test #2:
score: 0
Accepted
time: 1ms
memory: 5536kb
input:
ac ccpc
output:
5
result:
ok 1 number(s): "5"
Test #3:
score: 0
Accepted
time: 1ms
memory: 5524kb
input:
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq...
output:
75038697
result:
ok 1 number(s): "75038697"
Test #4:
score: -100
Wrong Answer
time: 1ms
memory: 5584kb
input:
lvvvllvllvllvllllllllvvvllvlllvvlvlvllvlvvlvvvvlvvllllllvvlvlvvlllvvlvlvllllllvlvvvvvvlllvvvllvlvvvlvvlllvvvvvvlvlllvvvvlvvvvvlvvlvvlllvvllvvllvlvlvlvlvllllvvllvvllvlllvvvllllvvlvvllvvvvlvlvvlvvlllvvvvvvvvlvvlvlllvllvvvvllvvvlvvvvvvlvlllvllllvllllllllvvllllllvlvvlvvvlvllllvllvlvvllllllvlvvvlvlvlvvvl...
output:
137595032
result:
wrong answer 1st numbers differ - expected: '538419149', found: '137595032'