結果
| 問題 |
No.2858 Make a Palindrome
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2024-08-25 16:29:02 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 3,693 bytes |
| コンパイル時間 | 1,859 ms |
| コンパイル使用メモリ | 200,428 KB |
| 最終ジャッジ日時 | 2025-02-24 01:56:47 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 16 WA * 24 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template<class T> istream& operator >> (istream& is, vector<T>& vec) {
for(T& x : vec) is >> x;
return is;
}
template<class T> ostream& operator << (ostream& os, const vector<T>& vec) {
if(vec.empty()) return os;
os << vec[0];
for(auto it = vec.begin(); ++it != vec.end(); ) os << ' ' << *it;
return os;
}
struct RollingHash{
long long BASE = 257, RMOD = (1ll<<61)-1;
long long MASK31 = (1ll<<31)-1, MASK30 = (1ll<<30)-1;
int n;
std::vector<long long> dat, dat2, base_pow;
RollingHash() {}
RollingHash(std::string &s) : n(s.size()), dat(n+1), dat2(n+1), base_pow(n+1) {
base_pow[0] = 1;
for(int i = 0; i < n; i++){
dat[i+1] = safe_mod(internal_mul(dat[i], BASE) + s[i]);
dat2.rbegin()[i+1] = safe_mod(internal_mul(dat2.rbegin()[i], BASE) + s.rbegin()[i]);
base_pow[i+1] = internal_mul(base_pow[i], BASE);
}
}
long long internal_mul(long long a, long long b){
long long au = a >> 31, ad = a & MASK31;
long long bu = b >> 31, bd = b & MASK31;
long long mid = ad * bu + au * bd;
long long midu = mid >> 30;
long long midd = mid & MASK30;
return safe_mod(au * bu * 2 + midu + (midd << 31) + ad * bd);
}
long long safe_mod(long long x){
long long xu = x >> 61, xd = x & RMOD;
long long res = xu + xd;
if (res >= RMOD) res -= RMOD;
return res;
}
long long hash(int l, int r){
long long res = dat[r] - internal_mul(dat[l], base_pow[r - l]);
if(res < 0)res += RMOD;
return res;
}
long long revhash(int l, int r){
long long res = dat2[l] - internal_mul(dat2[r], base_pow[r - l]);
if(res < 0)res += RMOD;
return res;
}
long long joint(long long lhs, long long rhs, long long rsize){
long long res = internal_mul(lhs, base_pow[rsize]) + rhs;
if(res >= RMOD) res -= RMOD;
return res;
}
};
bool para(string &s){
int l = 0, r = s.size() - 1;
while(l < r){
if(s[l] != s[r]) return false;
l++, r--;
}
return true;
}
vector<int> manacher(const string &s) {
vector<int> radius(s.size());
int i = 0, j = 0;
while(i < s.size()) {
while(i - j >= 0 && i + j < s.size() && s[i - j] == s[i + j]) {
++j;
}
radius[i] = j;
int k = 1;
while(i - k >= 0 && i + k < s.size() && k + radius[i - k] < j) {
radius[i + k] = radius[i - k];
++k;
}
i += k;
j -= k;
}
return radius;
}
int check(string &s){
int n = s.size();
RollingHash RH(s);
auto vec = manacher(s);
int ans = 0;
for(int i = 0; i < n; i++) ans = max(ans, 2 * vec[i] - 1);
for(int i = 1; i < n; i++){
int ok = 0, ng = min(i, n - i) + 1;
while(ok + 1 < ng){
int mid = (ok + ng) / 2;
if(RH.hash(i - mid, i) == RH.revhash(i, i + mid)) ok = mid;
else ng = mid;
}
ans = max(ans, ok * 2);
}
return ans;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin >> T;
while(T--){
int n, m;
string s;
cin >> n >> m >> s;
clock_t finish = clock() + (CLOCKS_PER_SEC / 1000 * 2300) * double(n) / 200000;
if(para(s)){
cout << (m + n - 1) / n << '\n';
continue;
}
string t;
int ans = -1;
for(int i = 1; clock() <= finish; i++){
t += s;
int v = check(t);
if(v >= m){
ans = i;
break;
}
if(v >= n){
ans = (m + n) / n;
break;
}
}
cout << ans << '\n';
}
}