제출 #1017366

#제출 시각아이디문제언어결과실행 시간메모리
1017366caterpillowMatching (CEOI11_mat)C++17
0 / 100
2094 ms50152 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; using pl = pair<ll, ll>; 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; template<template<typename> class Container, typename T> ostream& operator<<(ostream& os, Container<T> o) { os << "{"; int g = size(o); for (auto i : o) os << i << ((--g) == 0 ? "" : ", "); os << "}"; return os; } void _print() { cerr << "\n"; } template<typename T, typename ...V> void _print(T t, V... v) { cerr << t; if (sizeof...(v)) cerr << ", "; _print(v...); } #ifdef LOCAL #define dbg(x...) cerr << #x << " = "; _print(x); #else #define dbg(x...) #define cerr if (0) std::cerr #endif /* try sus kmp? precompute the indices i and j for each k in the pattern to quickly check is some building can be glued to the end of the current match a match is valid if and only if this is satisfied for all buildings compute a fallback array, such that if a mismatch happens on index i you can delete the first x amount to make the prefix match again compute an auxilliary array dp, where dp[i] = how far away the next mismatch is if you were to start matching at index i if you know that from index i, the first mismatched character is j, and that if you were to match with yourself from index 1 the next mismatched character is at 1 + k, then case 1: at index i + 1, you know for certain that index i + 1 + k is a mismatch, and i + 1 + k < j this means that you know the next mismatched position you can continue doing this until case 2 case 2: at index i + 1, you know for certain that index i + 1 + k is a mismatch, and i + 1 + k >= j who knows, it might match now! start checking again from index i + 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) { // cerr << "matching " << j << " starting from " << i << endl; 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++; cerr << "matched from " << i << " up to " << j << endl; dp[i] = j - i; cerr << "dp " << i << " = " << j - i << endl; int k = 1; cerr << i + k << " " << (i + k < m ? i + k + dp[k] : -1) << endl; while (i + k < m && i + k + dp[k] < j) { // case 1: we know the mismatch happens in our good prefix cerr << "we know the next mismatch\n"; dp[i + k] = dp[k]; cerr << "dp " << i + k << " = " << dp[k] << endl; k++; } i += k - 1; // case 2: idk whats happenign anymore } dbg(dp); } vt<int> fb; void compute_fallback() { fb.resize(m + 1); fb[0] = -1; vt<int> mod_dp = dp; // convert from next mismatch to last matching index relative to start mod_dp[0] = 1; dbg(mod_dp); vt<int> last(m + 1, m); ROF (i, 0, m) { fb[i + 1] = last[mod_dp[i]] - i; last[mod_dp[i]] = i; dbg(last); } dbg(fb); } main() { cin.tie(0)->sync_with_stdio(0); cin >> m >> n; pat.resize(m); F0R (i, m) { int v; cin >> v; pat[v - 1] = i; } comp.resize(m, {-1, -1}); map<int, int> prv; F0R (i, m) { auto it = prv.lower_bound(pat[i]); if (it != prv.end()) comp[i].s = it->s; if (it != prv.begin()) comp[i].f = prev(it)->s; prv[pat[i]] = i; } h.resize(n); F0R (i, n) cin >> h[i]; dbg(pat); F0R (i, m) { cerr << comp[i].f << " " << comp[i].s << endl; } compute_dp(); compute_fallback(); vt<int> out; int i = 0, j = 0; while (i < n) { while (j < n && j - i < m && match(i, j, h)) j++; cerr << "starting from " << i << ", mismatched at " << j << endl; // j is now at first mismatch if (j - i == m) out.pb(i); i += fb[j - i]; cerr << "i = " << i << endl; } cout << size(out) << endl; for (int e : out) cout << e + 1 << " "; cout << endl; }

컴파일 시 표준 에러 (stderr) 메시지

mat.cpp:127:1: warning: ISO C++ forbids declaration of 'main' with no type [-Wreturn-type]
  127 | main() {
      | ^~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...