이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
using ll = long long;
using pi = pair<int, int>;
#define vt vector
#define f first
#define s second
#define pb push_back
#define all(x) x.begin(), x.end()
#define size(x) ((int) (x).size())
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define ROF(i, a, b) for (int i = (b) - 1; i >= (a); i--)
#define F0R(i, b) FOR (i, 0, b)
#define endl '\n'
const ll INF = 1e18;
const int inf = 1e9;
inline namespace FastIO {
const int BSZ = 1 << 15;
char ibuf[BSZ]; int ipos, ilen;
char nc() {
if (ipos == ilen) {
ipos = 0;
ilen = fread(ibuf,1,BSZ,stdin);
if (!ilen) return EOF;
}
return ibuf[ipos++];
}
void rs(string& x) {
char ch; while (isspace(ch = nc()));
do { x += ch; } while (!isspace(ch = nc()) && ch != EOF);
}
template<class T> void ri(T& x) {
char ch;
int sgn = 1;
while (!isdigit(ch = nc())) if (ch == '-') sgn *= -1;
x = ch - '0';
while (isdigit(ch = nc())) x = x * 10 + (ch - '0');
x *= sgn;
}
template<class T, class... Ts> void ri(T& t, Ts&... ts) { ri(t); ri(ts...); }
char obuf[BSZ], numBuf[100]; int opos;
void flushOut() { fwrite(obuf,1,opos,stdout); opos = 0; }
void wc(char c) {
if (opos == BSZ) flushOut();
obuf[opos++] = c;
}
void ws(string s) { for (char& c : s) wc(c); }
template<class T> void wi(T x, char after = '\0') {
if (x < 0) wc('-'), x *= -1;
int len = 0;
for (; x >= 10; x /= 10) numBuf[len++] = '0' + (x % 10);
wc('0' + x);
ROF (i, 0, len) wc(numBuf[i]);
if (after) wc(after);
}
void initO() { assert(atexit(flushOut) == 0); }
}
/*
let fb[i] be how much you should shift your pattern to the right if you mismatch at index i
i cant be 0
let s be the prefix that we currently know matches
if there does not exist a suffix of this prefix which matches the prefix of s, then we can slide our pattern
to the end of s, since we know that it definitely wont match inside this prefix
however, if there does exist a suffix that matches the prefix, we can slide our pattern
such that our prefix is now aligned with this matching suffix
and then start matching from there
-------------------------------------------------------------------------------------------
let the pattern be p
let s be the prefix of the pattern of length i
fb[i] = the length of the longest suffix in s such that this suffix matches the prefix of s
define fb[0] = -1
if we can compute this array, then
if we know that we have a prefix of length i that matches the string (so char at index i is the first mismatch)
we can delete the first i - fb[i] characters of the string, and we will know that
characters up to fb[i] - 1 will match the pattern of this new string and index fb[i] may or may not be a mismatch
for example, the string abcdabc would have fb = [-1, 0, 0, 0, 0, 1, 2, 3]
-------------------------------------------------------------------------------------------
to compute this array, we would like to know many characters each suffix of the pattern p match with itself
for example, abcdabc would be [7, 0, 0, 0, 3, 0, 0]
let this array be called dp
then, calculating fb[i] in increasing i,
let j be the leftmost index among the indices strictly less than i such that j + dp[j] >= i
fb[i] = i - j
we need to exclude dp[0], since we only care about proper suffixes
-------------------------------------------------------------------------------------------
to calculate dp, idk
*/
// automatically pad on either side
struct DSU {
vt<int> e, rep;
void init(int n) {
e.resize(n + 2, -1);
rep.resize(n + 2); iota(all(rep), 0);
}
int _find(int x) { // just remember to add 1 before calling
return e[x] < 0 ? x : e[x] = _find(e[x]);
}
void _unite(int x, int y) {
x = _find(x), y = _find(y);
if (e[x] < e[y]) swap(x, y), swap(rep[x], rep[y]);
e[y] += e[x];
e[x] = y;
}
inline void unite(int x, int y) {
_unite(x + 1, y + 1);
}
inline int find(int x) {
return rep[_find(x + 1)] - 1;
}
};
int m, n;
vt<int> pat;
vt<pi> comp;
vt<int> h;
// check match at index j of the pattern starting at index i in str
bool match(int i, int j, vt<int>& str) {
pi prv = comp[j - i];
bool good = true;
if (prv.f != -1) good &= str[prv.f + i] < str[j];
if (prv.s != -1) good &= str[j] < str[prv.s + i];
return good;
}
vt<int> dp;
void compute_dp() {
dp.resize(m, inf);
dp[0] = 0;
int j = 1; // the first mismatched character starting from index i
FOR (i, 1, m) {
while (j < m && match(i, j, pat)) j++;
dp[i] = j - i;
int k = 1;
while (i + k < m && i + k + dp[k] < j) { // case 1: we know the mismatch happens in our good prefix
dp[i + k] = dp[k];
k++;
}
i += k - 1;
}
}
vt<int> fb;
void compute_fallback() {
fb.resize(m + 1, -1);
queue<int> q;
FOR (i, 1, m + 1) {
q.push(i - 1);
while (size(q) && q.front() + dp[q.front()] < i) q.pop();
if (!size(q)) fb[i] = 0;
else fb[i] = i - q.front();
}
}
using namespace FastIO;
main() {
cin.tie(0)->sync_with_stdio(0);
initO();
ri(m, n);
pat.resize(m);
F0R (i, m) ri(pat[i]), pat[i]--;
comp.resize(m, {-1, -1});
DSU next_lower, next_higher;
next_lower.init(m);
next_higher.init(m);
vt<int> rpat(m); F0R (i, m) rpat[pat[i]] = i;
ROF (i, 0, m) {
int lo = next_lower.find(pat[i] - 1);
int hi = next_higher.find(pat[i] + 1);
if (lo != -1) comp[i].f = rpat[lo];
if (hi != m) comp[i].s = rpat[hi];
next_lower.unite(pat[i], pat[i] - 1);
next_higher.unite(pat[i], pat[i] + 1);
}
h.resize(n);
F0R (i, n) ri(h[i]);
compute_dp();
compute_fallback();
vt<int> out;
int i = 0;
int off = 0;
while (i + off < n) {
while (i + off < n && i < m && match(off, off + i, h)) i++;
if (i == m) out.pb(off);
off += i - fb[i];
i = fb[i];
}
wi(size(out), '\n');
for (int e : out) wi(e + 1, ' ');
wc('\n');
}
컴파일 시 표준 에러 (stderr) 메시지
mat.cpp:180:1: warning: ISO C++ forbids declaration of 'main' with no type [-Wreturn-type]
180 | main() {
| ^~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |