제출 #679625

#제출 시각아이디문제언어결과실행 시간메모리
679625peijar세 명의 친구들 (BOI14_friends)C++17
35 / 100
1071 ms104232 KiB
#include <bits/stdc++.h> #define int long long using namespace std; namespace std { template <typename T> ostream &operator<<(ostream &out, const vector<T> &vec) { out << "["; for (int i = 0; i < (int)vec.size(); ++i) { out << vec[i]; if (i + 1 < (int)vec.size()) out << ", "; } return out << "]"; } } // namespace std void dbg_out() { cout << endl; } template <typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cout << ' ' << H; dbg_out(T...); } #ifdef DEBUG #define dbg(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__) #else #define dbg(...) #endif /* * sa[i] = starting index of i-th smallest suffix * sa.len() = n+ 1, sa[0] = n * lcp[i] = lcp(sa[i], sa[i-1]), lcp[0] = 0, len(sa) = n+1 */ template <class T> struct RMQ { vector<vector<T>> jmp; RMQ(const vector<T> &V) : jmp(1, V) { for (int pw = 1, k = 1; pw * 2 <= (int)V.size(); pw *= 2, ++k) { jmp.emplace_back((int)V.size() - pw * 2 + 1); for (int j = 0; j < (int)jmp[k].size(); ++j) jmp[k][j] = min(jmp[k - 1][j], jmp[k - 1][j + pw]); } } T query(int a, int b) { // [a, b) assert(a < b); int dep = 31 - __builtin_clz(b - a); return min(jmp[dep][a], jmp[dep][b - (1 << dep)]); } }; struct SuffixArray { vector<int> sa, lcp, rank; string s; RMQ<int> rmq; SuffixArray(string &_s, int lim = 256) : rmq({}) { s = _s; int n = s.size() + 1, k = 0, a, b; vector<int> x(s.begin(), s.end() + 1), y(n), ws(max(n, lim)); sa = lcp = rank = y, iota(sa.begin(), sa.end(), 0); for (int j = 0, p = 0; p < n; j = max(1LL, 2 * j), lim = p) { p = j, iota(y.begin(), y.end(), n - j); for (int i = 0; i < n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j; fill(ws.begin(), ws.end(), 0); for (int i = 0; i < n; ++i) ws[x[i]]++; for (int i = 1; i < lim; ++i) ws[i] += ws[i - 1]; for (int i = n; i--;) sa[--ws[x[y[i]]]] = y[i]; swap(x, y); p = 1, x[sa[0]] = 0; for (int i = 1; i < n; ++i) a = sa[i - 1], b = sa[i], x[b] = (y[a] == y[b] and y[a + j] == y[b + j]) ? p - 1 : p++; } for (int i = 1; i < n; ++i) rank[sa[i]] = i; for (int i = 0, j; i < n - 1; lcp[rank[i++]] = k) for (k &&k--, j = sa[rank[i] - 1]; s[i + k] == s[j + k]; k++) ; rmq = RMQ<int>(lcp); } int getLCP(int i, int j) { if (i == j) return s.size() - i; i = rank[i]; j = rank[j]; if (i > j) swap(i, j); return rmq.query(i + 1, j + 1); } }; bool get(string U) { int N = U.size() / 2; SuffixArray suffix(U); for (int skip = N; skip < 2 * N + 1; ++skip) { if (suffix.getLCP(0, N) < skip - N) continue; if (skip < 2 * N and suffix.getLCP(skip - N, skip + 1) < N - (skip - N)) continue; return true; } return false; } signed main(void) { ios_base::sync_with_stdio(false); cin.tie(0); int N; string U; cin >> N >> U; if (N % 2 == 0) { cout << "NOT POSSIBLE\n"; return 0; } string T = U; reverse(T.begin(), T.end()); bool okL = get(U); bool okR = get(T); N /= 2; string L = U.substr(0, N); string R = U.substr(N + 1, N); dbg(L, R); dbg(okL, okR); if (!okL and !okR) { cout << "NOT POSSIBLE\n"; return 0; } if (okL and okR and L != R) { cout << "NOT UNIQUE\n"; return 0; } cout << (okL ? L : R) << endl; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...