Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define all(x) begin(x),end(x)
- using namespace std;
- using ll = long long;
- mt19937 rnd(514234123);
- const ll mod1 = 1e9 + 7;
- const ll mod2 = 1e9 + 9;
- const ll a1 = 3e7 + 4123;
- const ll a2 = 3e7 + 141;
- template<ll A, ll MOD>
- struct THash {
- ll val;
- THash(ll k) : val(k % MOD) {}
- };
- template<ll MOD>
- ll FastPower(ll a, int p) {
- ll res = 1;
- while (p) {
- if (p & 1) {
- res *= a;
- res %= MOD;
- }
- a = (a * a) % MOD;
- p >>= 1;
- }
- return res;
- }
- template<ll A, ll MOD>
- THash<A, MOD> merge(THash<A, MOD> l, THash<A, MOD> r, int lsz) {
- return THash<A, MOD>(l.val * FastPower<MOD>(A, lsz) + r.val);
- }
- struct Treap {
- Treap *l = nullptr;
- Treap *r = nullptr;
- int sz = 0;
- ll key;
- ll pr;
- THash<a1, mod1> hsh;
- THash<a2, mod2> hsh2;
- explicit Treap(ll k) : key(k), sz(1), pr(rnd()), hsh(key), hsh2(key) {}
- };
- int gsz(Treap *v) {
- return v ? v->sz : 0;
- }
- void rsz(Treap *v) {
- v->sz = gsz(v->l) + gsz(v->r) + 1;
- }
- void upd(Treap *v) {
- rsz(v);
- if (v->l) {
- v->hsh = v->l->hsh;
- v->hsh2 = v->l->hsh2;
- } else {
- v->hsh = {0};
- v->hsh2 = {0};
- }
- if (v->r) {
- v->hsh = merge(v->hsh, v->r->hsh, gsz(v->l));
- v->hsh2 = merge(v->hsh2, v->r->hsh2, gsz(v->l));
- }
- }
- Treap *merge(Treap *l, Treap *r) {
- if (!l || !r) return l ? l : r;
- if (l->pr > r->pr) {
- l->r = merge(l->r, r);
- upd(l);
- return l;
- } else {
- r->l = merge(l, r->l);
- upd(r);
- return r;
- }
- }
- bool eq(Treap *l, Treap *r) {
- if (!l || !r) return false;
- return l->hsh.val == r->hsh.val && l->hsh2.val == r->hsh2.val;
- }
- pair<Treap *, Treap *> split(Treap *v, int sz) {
- if (!v || sz >= gsz(v)) return {v, nullptr};
- if (gsz(v->l) + 1 <= sz) {
- auto[l, r] = split(v->r, sz - 1 - gsz(v->l));
- v->r = l;
- upd(v);
- return {v, r};
- } else {
- auto[l, r] = split(v->l, sz);
- v->l = r;
- upd(v);
- return {l, v};
- }
- }
- struct SegmentTree {
- vector<int> t;
- explicit SegmentTree(int n) : t(n * 4, -1) {}
- void Update(int v, int tl, int tr, int i, int val) {
- if (tl + 1 == tr) {
- t[v] = val;
- } else {
- int tm = (tl + tr) >> 1;
- if (i < tm) {
- Update(v * 2 + 1, tl, tm, i, val);
- } else {
- Update(v * 2 + 2, tm, tr, i, val);
- }
- t[v] = max(t[v * 2 + 1], t[v * 2 + 2]);
- }
- }
- int Get(int v, int tl, int tr, int l, int r) {
- if (tl >= r || tr <= l) return -1;
- if (tl >= l && tr <= r) {
- return t[v];
- } else {
- int tm = (tl + tr) >> 1;
- return max(Get(v * 2 + 1, tl, tm, l, r), Get(v * 2 + 2, tm, tr, l, r));
- }
- }
- };
- vector<pair<int, int>> prep(vector<int> &a) {
- set<int> st(all(a));
- int itr = 0;
- map<int, int> mp;
- for (auto &x: st) mp[x] = itr++;
- for (auto &x: a) x = mp[x];
- int sz = (int) st.size();
- SegmentTree tree(sz);
- vector<pair<int, int>> res(a.size(), {-1, a.size()});
- int n = (int) a.size();
- for (int i = 0; i < n; i++) {
- int f = res[i].first = tree.Get(0, 0, sz, a[i], sz);
- if (f != -1) {
- res[f].second = min(res[f].second, i);
- }
- tree.Update(0, 0, sz, a[i], i);
- }
- for (int i = 0; i < n; i++) {
- auto&[l, r] = res[i];
- l -= i;
- r -= i;
- }
- return res;
- }
- ll getKey(int l, int r, int m) {
- l += m;
- r += m;
- return ll(1e9) * l + r;
- }
- ll getKey(pair<int, int> p, int m) {
- return getKey(p.first, p.second, m);
- }
- void solve() {
- int m, n;
- cin >> m >> n;
- vector<int> a(m), b(n);
- for (auto &x: a) cin >> x;
- for (auto &x: b) cin >> x;
- auto arr = prep(a);
- auto brr = prep(b);
- vector<vector<int>> rem(brr.size()), add(brr.size());
- for (int i = 0; i < n; i++) {
- auto[l, r] = brr[i];
- l += i;
- r += i;
- if (l != -1) {
- rem[l].push_back(i);
- }
- if (r != n) {
- add[r].push_back(i);
- }
- }
- Treap *at = nullptr;
- for (int i = 0; i < m; i++) {
- cout << "a = " << arr[i].first << ' ' << arr[i].second << endl;
- at = merge(at, new Treap(getKey(arr[i].first, arr[i].second, m)));
- }
- Treap *br = nullptr;
- int cl = 0;
- int cr = m - 1;
- for (int i = 0; i < m - 1; i++) {
- auto[l, r] = brr[i];
- r = min(r, cr + 1);
- cout << "b= " << l << ' ' << r << endl;
- br = merge(br, new Treap(getKey(l, r, m)));
- }
- vector<int> ans;
- for (int i = m - 1; i < n; i++) {
- auto[l, r] = brr[i];
- r = min(r, 1);
- l = max(l, -m);
- br = merge(br, new Treap(getKey(l, r, m)));
- if (i > m - 1) {
- auto[tl, tr] = split(br, 1);
- br = tr;
- }
- /*
- 5 10
- 500 560 600 680 580
- 40 60 70 90 65 30 35 50 55 40
- */
- for (auto ind: add[i]) {
- if (cl <= ind && ind <= cr) {
- auto[xl, xr] = brr[ind];
- auto pos = ind - cl;
- auto[kekl, kek] = split(br, pos);
- auto[ffl, kekr] = split(kek, 1);
- int mxl = -pos - 1;
- int mxr = cr - ind + 1;
- auto *nxt = new Treap(getKey(max(mxl, xl), min(xr, mxr), m));
- br = merge(kekl, nxt);
- br = merge(br, kekr);
- }
- }
- cout << at->hsh.val << ' ' << at->hsh2.val << endl;
- cout << br->hsh.val << ' ' << br->hsh2.val << endl;
- if (eq(at, br)) {
- ans.push_back(i - m + 2);
- }
- for (auto ind: rem[i]) {
- if (cl <= ind && ind <= cr) {
- auto[xl, xr] = brr[ind];
- auto pos = ind - cl;
- auto[kekl, kek] = split(br, pos);
- auto[ffl, kekr] = split(kek, 1);
- int mxl = -pos - 1;
- int mxr = cr - ind + 1;
- auto *nxt = new Treap(getKey(max(mxl, xl), min(xr, mxr), m));
- br = merge(kekl, nxt);
- br = merge(br, kekr);
- }
- }
- cl++;
- cr++;
- }
- if (ans.empty()) ans = {0};
- for (auto val: ans) cout << val << ' ';
- cout << '\n';
- }
- int main() {
- ios_base::sync_with_stdio(false);
- cin.tie(nullptr);
- cout.tie(nullptr);
- solve();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement