# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
1178723 | vominhhuy123 | Matching (CEOI11_mat) | C++20 | 0 ms | 0 KiB |
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
const ull OFFSET = 1469598103934665603ULL;
const ull PRIME = 1099511628211ULL;
struct SegTree {
int n;
vector<int> tree;
const vector<int>& arr;
SegTree(const vector<int>& a) : arr(a) {
n = a.size();
tree.resize(4*n);
build(1, 0, n-1);
}
void build(int idx, int l, int r) {
if(l == r) {
tree[idx] = l;
return;
}
int mid = (l + r) >> 1;
build(idx*2, l, mid);
build(idx*2+1, mid+1, r);
int leftIdx = tree[idx*2], rightIdx = tree[idx*2+1];
tree[idx] = (arr[leftIdx] < arr[rightIdx] ? leftIdx : rightIdx);
}
int query(int idx, int l, int r, int ql, int qr) const {
if(ql > r || qr < l)
return -1;
if(ql <= l && r <= qr)
return tree[idx];
int mid = (l + r) >> 1;
int leftAns = query(idx*2, l, mid, ql, qr);
int rightAns = query(idx*2+1, mid+1, r, ql, qr);
if(leftAns == -1) return rightAns;
if(rightAns == -1) return leftAns;
return (arr[leftAns] < arr[rightAns] ? leftAns : rightAns);
}
int query(int ql, int qr) const {
return query(1, 0, n-1, ql, qr);
}
};
const ull EMPTY_HASH = 1234567ULL;
ull getHash(int L, int R, const vector<int>& a, const SegTree &seg) {
if(L > R)
return EMPTY_HASH;
int pos = seg.query(L, R);
ull leftH = getHash(L, pos - 1, a, seg);
ull rightH = getHash(pos + 1, R, a, seg);
ull h = OFFSET;
h ^= leftH; h *= PRIME;
h ^= 0x9e3779b97f4a7c15ULL; h *= PRIME;
h ^= rightH; h *= PRIME;
return h;
}
int main(){
int n, m;
if(scanf("%d %d", &n, &m) != 2)
return 1;
vector<int> logoInput(n);
for (int i = 0; i < n; i++) {
scanf("%d", &logoInput[i]);
// the input permutation is 1-indexed; here logoInput[i] is s[i+1]
}
vector<int> buildings(m);
for (int i = 0; i < m; i++)
scanf("%d", &buildings[i]);
SegTree segLogo(pattern);
vector<int> pattern(n);
for (int i = 0; i < n; i++) {
int stripePos = logoInput[i] - 1;
pattern[stripePos] = i + 1; // ranks from 1 to n
}
SegTree segBuildings(buildings);
ull logoHash = getHash(0, n - 1, pattern, segLogo);
vector<int> answer;
for (int start = 0; start <= m - n; start++) {
ull curHash = getHash(start, start + n - 1, buildings, segBuildings);
if(curHash == logoHash)
answer.push_back(start + 1);
}
printf("%d\n", (int)answer.size());
if(!answer.empty()){
for (int i = 0; i < (int)answer.size(); i++) {
if(i) printf(" ");
printf("%d", answer[i]);
}
printf("\n");
} else {
printf("\n");
}
return 0;
}