QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#402586 | #4275. Escape Sequences | I_Love_Sonechka# | WA | 1ms | 3596kb | C++17 | 5.1kb | 2024-04-30 23:12:14 | 2024-04-30 23:12:14 |
Judging History
answer
#include <bits/stdc++.h>
#include <math.h>
using namespace std;
// c++ short types
#define vt vector
typedef long long ll;
typedef long double ld;
void whattime() { cout << "finished in " << clock() * 1.0 / CLOCKS_PER_SEC << " sec" << endl; }
const ll inf = 1e18;
#include <bits/stdc++.h>
#include <math.h>
using namespace std;
#define fastio cin.tie(0); cin.sync_with_stdio(0);
#define pres(y) fixed << setprecision(y)
typedef pair<int, int> pi;
typedef long long ll;
typedef unsigned long long ull;
// Генерация случайного основания хэширования на отрезке (before, after):
int gen_base(const int before, const int after) {
auto seed = std::chrono::high_resolution_clock::now().time_since_epoch().count();
std::mt19937 mt_rand(seed);
int base = std::uniform_int_distribution<int>(before+1, after)(mt_rand);
return base % 2 == 0 ? base-1 : base;
}
struct Hash {
// -------- Статические переменные класса --------
static const int mod = (int)1e9+123; // простой модуль полиномиального хэширования
static std::vector<int> pow1; // степени основания base по модулю mod
static std::vector<ull> pow2; // степени основания base по модулю 2^64
static int base; // основание base
// --------- Статические функции класса ---------
static inline int diff(int a, int b) { // разность a и b по модуль mod (Предполагается: 0 <= a < mod, 0 <= b < mod)
return (a -= b) < 0 ? a + mod : a;
}
// -------------- Переменные класса -------------
std::vector<int> pref1; // Полиномиальный хэш на префиксе по модулю mod
std::vector<ull> pref2; // Полиномиальный хэш на префиксе по модулю 2^64
Hash() {}
// Конструктор от строки:
Hash(const vt<int> &s)
: pref1(s.size()+1u, 0)
, pref2(s.size()+1u, 0)
{
assert(base < mod);
const int n = s.size(); // Досчитываем необходимые степени основания по модулям хэширования
while ((int)pow1.size() <= n) {
pow1.push_back(1LL * pow1.back() * base % mod);
pow2.push_back(pow2.back() * base);
}
for (int i = 0; i < n; ++i) { // Заполняем массив полиномиальных хэшей на префиксе
assert(base > s[i]);
pref1[i+1] = (pref1[i] + 1LL * s[i] * pow1[i]) % mod;
pref2[i+1] = pref2[i] + s[i] * pow2[i];
}
}
// Полиномиальный хэш подпоследовательности [pos, pos+len)
// Если mxPow != 0, то происходит домножение значения до старшей степени base ^ mxPow
inline std::pair<int, ull> operator()(const int pos, const int len, const int mxPow = 0) const {
int hash1 = pref1[pos+len] - pref1[pos];
ull hash2 = pref2[pos+len] - pref2[pos];
if (hash1 < 0) hash1 += mod;
if (mxPow != 0) {
hash1 = 1LL * hash1 * pow1[mxPow-(pos+len-1)] % mod;
hash2 *= pow2[mxPow-(pos+len-1)];
}
return std::make_pair(hash1, hash2);
}
};
// Инициализация статических объектов класса Hash:
int Hash::base((int)1e9+7);
std::vector<int> Hash::pow1{1};
std::vector<ull> Hash::pow2{1};
void solve() {
Hash::base = gen_base(256, Hash::mod);
string s, t;
cin >> s >> t;
if(accumulate(s.begin(), s.end(), 0) - s.size() * 'a' < accumulate(t.begin(), t.end(), 0) - t.size() * 'a') {
cout << "-1\n";
return ;
}
auto Get1 = [](int k) {
return 1 << min(k, 22);
};
auto Get2 = [](int k) {
return (1 << min(k, 23)) - 1;
};
const int amax = 4e5;
auto f = [&](int k) {
int left = -1, right = 0;
vt<int> a;
if(accumulate(t.begin(), t.end(), 0) == t.size() * 'a') {
left = t.size();
} else {
for (int i = 0; i < (int) t.size(); ++i) {
if (t[i] == 'b') {
int j = i;
while (j + 1 < t.size() && t[j + 1] == 'a') ++j;
a.push_back(j - i);
if (left == -1) {
left = i;
}
}
}
right = a.back();
a.pop_back();
}
vt<int> b;
int cnt = 0;
for (int i = 0; i < (int) s.size(); ++i) {
if (s[i] == 'b') {
b.push_back(
min(1ll * amax, cnt * 1ll * Get1(k) + Get2(k))
);
} else {
++cnt;
}
}
b.push_back(min(1ll * amax, cnt * 1ll * Get1(k)));
if(a.empty()) {
for(int i = 0; i + 1 < b.size(); ++i) {
if(b[i] >= left && b[i] >= right) {
return true;
}
}
return false;
}
Hash ha(a), hb(b);
int len = (int)a.size();
for(int i = 1; i + len < b.size(); ++i) {
if(b[i-1] >= left && b[i + len] >= right && ha(0, k, b.size()) == hb(i, k, b.size())) {
return true;
}
}
return false;
};
for(int i = 0; i < 21; ++i) {
if(f(i)) {
cout << i << "\n";
return ;
}
}
cout << "-1\n";
}
int main()
{
int tt = 1;
for(int t = 0; t < tt; ++t) {
solve();
}
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 1ms
memory: 3596kb
input:
b ab
output:
1
result:
ok 1 number(s): "1"
Test #2:
score: 0
Accepted
time: 0ms
memory: 3552kb
input:
ababa bab
output:
0
result:
ok 1 number(s): "0"
Test #3:
score: 0
Accepted
time: 1ms
memory: 3584kb
input:
a b
output:
-1
result:
ok 1 number(s): "-1"
Test #4:
score: -100
Wrong Answer
time: 0ms
memory: 3536kb
input:
abbb baa
output:
1
result:
wrong answer 1st numbers differ - expected: '2', found: '1'