結果
問題 | No.2454 Former < Latter |
ユーザー |
![]() |
提出日時 | 2023-09-01 22:55:12 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 15,850 bytes |
コンパイル時間 | 3,633 ms |
コンパイル使用メモリ | 236,584 KB |
最終ジャッジ日時 | 2025-02-16 17:10:03 |
ジャッジサーバーID (参考情報) |
judge4 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 6 WA * 17 |
ソースコード
/*** code generated by JHelper* More info: https://github.com/AlexeyDmitriev/JHelper* @author*///@formatter:off#pragma GCC optimize("Ofast")#include <bits/stdc++.h>using namespace std;#include <algorithm>#include <cassert>#include <numeric>#include <string>#include <vector>namespace atcoder {namespace internal {std::vector<int> sa_naive(const std::vector<int>& s) {int n = int(s.size());std::vector<int> sa(n);std::iota(sa.begin(), sa.end(), 0);std::sort(sa.begin(), sa.end(), [&](int l, int r) {if (l == r) return false;while (l < n && r < n) {if (s[l] != s[r]) return s[l] < s[r];l++;r++;}return l == n;});return sa;}std::vector<int> sa_doubling(const std::vector<int>& s) {int n = int(s.size());std::vector<int> sa(n), rnk = s, tmp(n);std::iota(sa.begin(), sa.end(), 0);for (int k = 1; k < n; k *= 2) {auto cmp = [&](int x, int y) {if (rnk[x] != rnk[y]) return rnk[x] < rnk[y];int rx = x + k < n ? rnk[x + k] : -1;int ry = y + k < n ? rnk[y + k] : -1;return rx < ry;};std::sort(sa.begin(), sa.end(), cmp);tmp[sa[0]] = 0;for (int i = 1; i < n; i++) {tmp[sa[i]] = tmp[sa[i - 1]] + (cmp(sa[i - 1], sa[i]) ? 1 : 0);}std::swap(tmp, rnk);}return sa;}template <int THRESHOLD_NAIVE = 10, int THRESHOLD_DOUBLING = 40>std::vector<int> sa_is(const std::vector<int>& s, int upper) {int n = int(s.size());if (n == 0) return {};if (n == 1) return {0};if (n == 2) {if (s[0] < s[1]) {return {0, 1};} else {return {1, 0};}}if (n < THRESHOLD_NAIVE) {return sa_naive(s);}if (n < THRESHOLD_DOUBLING) {return sa_doubling(s);}std::vector<int> sa(n);std::vector<bool> ls(n);for (int i = n - 2; i >= 0; i--) {ls[i] = (s[i] == s[i + 1]) ? ls[i + 1] : (s[i] < s[i + 1]);}std::vector<int> sum_l(upper + 1), sum_s(upper + 1);for (int i = 0; i < n; i++) {if (!ls[i]) {sum_s[s[i]]++;} else {sum_l[s[i] + 1]++;}}for (int i = 0; i <= upper; i++) {sum_s[i] += sum_l[i];if (i < upper) sum_l[i + 1] += sum_s[i];}auto induce = [&](const std::vector<int>& lms) {std::fill(sa.begin(), sa.end(), -1);std::vector<int> buf(upper + 1);std::copy(sum_s.begin(), sum_s.end(), buf.begin());for (auto d : lms) {if (d == n) continue;sa[buf[s[d]]++] = d;}std::copy(sum_l.begin(), sum_l.end(), buf.begin());sa[buf[s[n - 1]]++] = n - 1;for (int i = 0; i < n; i++) {int v = sa[i];if (v >= 1 && !ls[v - 1]) {sa[buf[s[v - 1]]++] = v - 1;}}std::copy(sum_l.begin(), sum_l.end(), buf.begin());for (int i = n - 1; i >= 0; i--) {int v = sa[i];if (v >= 1 && ls[v - 1]) {sa[--buf[s[v - 1] + 1]] = v - 1;}}};std::vector<int> lms_map(n + 1, -1);int m = 0;for (int i = 1; i < n; i++) {if (!ls[i - 1] && ls[i]) {lms_map[i] = m++;}}std::vector<int> lms;lms.reserve(m);for (int i = 1; i < n; i++) {if (!ls[i - 1] && ls[i]) {lms.push_back(i);}}induce(lms);if (m) {std::vector<int> sorted_lms;sorted_lms.reserve(m);for (int v : sa) {if (lms_map[v] != -1) sorted_lms.push_back(v);}std::vector<int> rec_s(m);int rec_upper = 0;rec_s[lms_map[sorted_lms[0]]] = 0;for (int i = 1; i < m; i++) {int l = sorted_lms[i - 1], r = sorted_lms[i];int end_l = (lms_map[l] + 1 < m) ? lms[lms_map[l] + 1] : n;int end_r = (lms_map[r] + 1 < m) ? lms[lms_map[r] + 1] : n;bool same = true;if (end_l - l != end_r - r) {same = false;} else {while (l < end_l) {if (s[l] != s[r]) {break;}l++;r++;}if (l == n || s[l] != s[r]) same = false;}if (!same) rec_upper++;rec_s[lms_map[sorted_lms[i]]] = rec_upper;}auto rec_sa =sa_is<THRESHOLD_NAIVE, THRESHOLD_DOUBLING>(rec_s, rec_upper);for (int i = 0; i < m; i++) {sorted_lms[i] = lms[rec_sa[i]];}induce(sorted_lms);}return sa;}} // namespace internalstd::vector<int> suffix_array(const std::vector<int>& s, int upper) {assert(0 <= upper);for (int d : s) {assert(0 <= d && d <= upper);}auto sa = internal::sa_is(s, upper);return sa;}template <class T> std::vector<int> suffix_array(const std::vector<T>& s) {int n = int(s.size());std::vector<int> idx(n);iota(idx.begin(), idx.end(), 0);sort(idx.begin(), idx.end(), [&](int l, int r) { return s[l] < s[r]; });std::vector<int> s2(n);int now = 0;for (int i = 0; i < n; i++) {if (i && s[idx[i - 1]] != s[idx[i]]) now++;s2[idx[i]] = now;}return internal::sa_is(s2, now);}std::vector<int> suffix_array(const std::string& s) {int n = int(s.size());std::vector<int> s2(n);for (int i = 0; i < n; i++) {s2[i] = s[i];}return internal::sa_is(s2, 255);}template <class T>std::vector<int> lcp_array(const std::vector<T>& s,const std::vector<int>& sa) {int n = int(s.size());assert(n >= 1);std::vector<int> rnk(n);for (int i = 0; i < n; i++) {rnk[sa[i]] = i;}std::vector<int> lcp(n - 1);int h = 0;for (int i = 0; i < n; i++) {if (h > 0) h--;if (rnk[i] == 0) continue;int j = sa[rnk[i] - 1];for (; j + h < n && i + h < n; h++) {if (s[j + h] != s[i + h]) break;}lcp[rnk[i] - 1] = h;}return lcp;}std::vector<int> lcp_array(const std::string& s, const std::vector<int>& sa) {int n = int(s.size());std::vector<int> s2(n);for (int i = 0; i < n; i++) {s2[i] = s[i];}return lcp_array(s2, sa);}template <class T> std::vector<int> z_algorithm(const std::vector<T>& s) {int n = int(s.size());if (n == 0) return {};std::vector<int> z(n);z[0] = 0;for (int i = 1, j = 0; i < n; i++) {int& k = z[i];k = (j + z[j] <= i) ? 0 : std::min(j + z[j] - i, z[i - j]);while (i + k < n && s[k] == s[i + k]) k++;if (j + z[j] < i + z[i]) j = i;}z[0] = n;return z;}std::vector<int> z_algorithm(const std::string& s) {int n = int(s.size());std::vector<int> s2(n);for (int i = 0; i < n; i++) {s2[i] = s[i];}return z_algorithm(s2);}} // namespace atcoder//@formatter:off#define rep(i, n) for (int i = 0; i < (n); ++i)#define drep(i, n) for (int i = (n)-1; i >= 0; --i)#define srep(i, s, t) for (int i = s; i < t; ++i)#define rng(a) a.begin(), a.end()#define rrng(a) a.rbegin(), a.rend()using ll = long long;using P = pair<ll, ll>;using VI = vector<int>;using VVI = vector<VI>;using VVVI = vector<VVI>;using VVVVI = vector<VVVI>;using VL = vector<ll>;using VVL = vector<VL>;using VVVL = vector<VVL>;using VVVVL = vector<VVVL>;using VP = vector<P>;using VVP = vector<vector<P>>;using VS = vector<string>;using VC = vector<char>;using VVC = vector<vector<char>>;using VD = vector<double>;using VVD = vector<vector<double>>;using VVVD = vector<VVD>;using I_I = pair<int, int>;const int INF = (int)1e9 + 10; // int max > 2*10^9const long long INFL = (ll)2e18 + 10; // ll max > 9*10^18const int JU_5 = 100000;const int JU_6 = 1000000;const ll JU_9 = 1000000000;const ll JU_18 = JU_9*JU_9;#define YES cout << "YES" << endl#define NO cout << "NO" << endl#define Yes cout << "Yes" << endl#define No cout << "No" << endltemplate <typename T, typename C>pair<T,C> operator+(const pair<T,C> &a, const pair<T,C> &b) { return make_pair(a.first + b.first, a.second + b.second); }template <typename T, typename C>pair<T,C> operator-(const pair<T,C> &a, const pair<T,C> &b) { return make_pair(a.first - b.first, a.second - b.second); }template <typename T, typename C>pair<T,C> operator*(const pair<T,C> &a, const pair<T,C> &b) { return make_pair(a.first * b.first, a.second * b.second); }template <typename T, typename C>pair<T,C> operator/(const pair<T,C> &a, const pair<T,C> &b) { return make_pair(a.first / b.first, a.second / b.second); }// #define MOD 1000000007#define MOD 998244353#define pmod(x,y) ((x%y)+y)%y/********** libs **********///@formatter:off// jhelper 用変数ostream *__cout;istream *__cin;void _init_io(std::istream &cin, std::ostream &cout) {// 入出力高速化用ios::sync_with_stdio(false); cin.tie(nullptr);cout << std::setprecision(30);// jhelper 用__cout = &cout; __cin = &cin;}//@formatter:off/* デバッグ用 出力 */template<typename T>ostream &operator<<(ostream &os, const deque<T> &vec) { os << "deq["; for (auto v: vec) os << v << ","; os << "]"; return os; }template<typename T>ostream &operator<<(ostream &os, const set<T> &vec) { os << "{"; for (auto v: vec) os << v << ","; os << "}"; return os; }template<typename T>ostream &operator<<(ostream &os, const unordered_set<T> &vec) { os << "{"; for (auto v: vec) os << v << ","; os << "}"; return os; }template<typename T>ostream &operator<<(ostream &os, const multiset<T> &vec) { os << "{"; for (auto v: vec) os << v << ","; os << "}"; return os; }template<typename T>ostream &operator<<(ostream &os, const unordered_multiset<T> &vec) { os << "{"; for (auto v: vec) os << v << ","; os << "}"; return os; }template<typename T1, typename T2>ostream &operator<<(ostream &os, const pair<T1, T2> &pa) { os << "(" << pa.first << "," << pa.second << ")"; return os; }template<typename TK, typename TV>ostream &operator<<(ostream &os, const map<TK, TV> &mp) { os << "{"; for (auto v: mp) os << v.first << "=>" << v.second << ","; os << "}"; return os;}template<typename TK, typename TV>ostream &operator<<(ostream &os, const unordered_map<TK, TV> &mp) { os << "{"; for (auto v: mp) os << v.first << "=>" << v.second << ","; os << "}";return os; }// print like python// src: https://qiita.com/Lily0727K/items/06cb1d6da8a436369eed/////////////////////////////////////////////////////////void print() { *__cout << '\n'; }template<class Head, class... Tail>void print(Head &&head, Tail &&... tail) { *__cout << head; if (sizeof...(tail) != 0) *__cout << " "; print(forward<Tail>(tail)...); }template<class T>void print(vector<T> &vec) { for (auto &a: vec) { *__cout << a; if (&a != &vec.back()) *__cout << " "; } *__cout << '\n'; }template<class T>void print(vector<vector<T>> &df) { for (auto &vec: df) { print(vec); } }// endl なしvoid Print() {}template<class Head, class... Tail>void Print(Head &&head, Tail &&... tail) { *__cout << head; if (sizeof...(tail) != 0) *__cout << " "; Print(forward<Tail>(tail)...); }template<class T>void Print(vector<T> &vec) { for (auto &a: vec) { *__cout << a; if (&a != &vec.back()) *__cout << " "; } }//@formatter:off/** org: https://atcoder.jp/contests/abc213/submissions/24901856* jhelper で使用するため, 全部 cin での入力にしている. (現状のレベルでは困らないので)*/template<class T> void scan(T& a){ *__cin >> a; }template<class T> void scan(vector<T>&);template<class T, class L> void scan(pair<T, L>&);template<class T> void scan(vector<T>& a){ for(auto&& i : a) scan(i); }template<class T, class L> void scan(pair<T, L>& p){ scan(p.first); scan(p.second); }template<class T, size_t size> void scan(T (&a)[size]){ for(auto&& i : a) scan(i); }void in(){}template <class... T> void in(T&... a){ (void)initializer_list<int>{ (scan(a), 0)... }; }#define let_v(type,name,...) vector<type>name(__VA_ARGS__)#define let_V(type,name,size) vector<type>name(size);in(name)#define let_vv(type,name,h,...) vector<vector<type>>name(h,vector<type>(__VA_ARGS__))#define let_VV(type,name,h,w) vector<vector<type>>name(h,vector<type>(w));in(name)#define let_vvv(type,name,h,w,...) vector<vector<vector<type>>>name(h,vector<vector<type>>(w,vector<type>(__VA_ARGS__)))#define let_vvvv(type,name,h,w,x,...) vector<vector<vector<vector<type>>>>name(h,vector<vector<vector<type>>>(w,vector<vector<type>>(x,vector<type>(__VA_ARGS__))))#define let_vvvvv(type,name,h,w,x,y,...) vector<vector<vector<vector<vector<type>>>>>name(h,vector<vector<vector<vector<type>>>>(w,vector<vector<vector<type>>>(x,vector<vector<type>>(y,vector<type>(__VA_ARGS__)))))/* string 入力を vector<char> で受け取るみたいな */vector<char> let_CharVec() { string s; *__cin >> s; return {s.begin(), s.end()}; }//@formatter:off//ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }template <class T, class C>bool chmax(T& a, C b) { if (a < b) { a = b; return true; } return false; }template <class T, class C>bool chmin(T& a, C b) { if (a > b) { a = b; return true; } return false; }template <class T>T sum(const vector<T>& v) { T res = 0; for (size_t i = 0; i < v.size(); ++i) res += v[i]; return res; }//template <class T, class C>//T min(T a, C b) { return a <= b ? a : T(b); }////template <class T, class C>//T max(T a, C b) { return a >= b ? a : T(b); }template<class T>vector<pair<T, int>> idx_pair(vector<T> &vals) { vector<pair<T, int>> ans; rep(i, vals.size()) { ans.emplace_back(vals[i], i); } return ans; }template<typename T>int argmax(vector<T> &vals){ if(vals.size()==0)return -1; int res=0; for(int i = 1;i<vals.size();i++){ if(vals[i]>vals[res])res=i; } return res; }template<typename T>int argmin(vector<T> &vals){ if(vals.size()==0)return -1; int res=0; for(int i = 1;i<vals.size();i++){ if(vals[i]<vals[res])res=i; } return res; }// add other source// #include "../library/graph/UnionFind.cpp"// #include "../library/others/Zaatsu.cpp"// #include "../library/graph/template.cpp"// utils// #include "../library/mint.cpp"// #include "../library/string/utils.cpp"// #include "../library/math/utils.cpp"/**************************/class unko {public:void solve(std::istream &cin, std::ostream &cout) { _init_io(cin, cout); int t = 1;cin >> t;while (t--) _solve(cin, cout); }//@formatter:onvoid _solve(std::istream &cin, std::ostream &cout) {// codeint n;string s;cin >> n >> s;auto res = atcoder::suffix_array(s);auto z = atcoder::z_algorithm(s);// print(res);// print(z);ll tot = 0;bool flg = false;rep(i, n) {int idx = res[i];if (idx == 0)flg = true;else if (flg) tot++;}// print(z);drep(i, n) {if (i > n / 2) {if (z[i] == n - i){// print("add",i);tot++;}} else {if(n%2==0&&n/2==i){continue;}if(z[i]==i){// print("add",i);tot++;}}}print(tot);}};int main() {unko solver;std::istream& in(std::cin);std::ostream& out(std::cout);solver.solve(in, out);return 0;}