Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // clang-format off
- #define _CRT_SECURE_NO_WARNINGS
- #include <iostream>
- #include <iomanip>
- #include <bitset>
- #include <vector>
- #include <algorithm>
- #include <random>
- #include <map>
- #include <string>
- #include <set>
- #include <deque>
- #include <string>
- #include <cassert>
- #pragma GCC optimize("Ofast")
- using namespace std;
- const int N = 1e6 + 7, MOD = 998244353, M = 139;
- const long double EPS = 1e-10, PI = acos(-1);
- using ll = long long;
- ll binpow(ll a, int step) {
- if (step == 0) {
- return 1;
- }
- ll h = binpow(a, step / 2);
- h = (h * h) % MOD;
- if (step % 2) {
- h = (h * a) % MOD;
- }
- return h;
- }
- ll pows[N];
- ll q = 149;
- struct Hash {
- ll hsh = 0;
- int len;
- void pop_back(int a) {
- hsh -= ((a + 1) * pows[len - 1]) % MOD;
- if (hsh < 0) {
- hsh += MOD;
- }
- len--;
- }
- void push_front(int a) {
- hsh *= q;
- hsh += a + 1;
- hsh %= MOD;
- len++;
- }
- };
- Hash fwd[N], fwd2[N];
- int a[N], b[N], n, m, q1, bwd[N];
- int z[N];
- vector<int> s;
- bool good[N];
- void zfun() {
- int n = s.size();
- z[0] = 0;
- int L = 0, R = 0;
- for (int i = 1; i < n; i++) {
- z[i] = max(0, min(z[i - L], R - i+1));
- while (i + z[i] < n && s[i + z[i]] == s[z[i]]) {
- z[i]++;
- }
- if (i + z[i] - 1 > R) {
- L = i;
- R = i + z[i] - 1;
- }
- }
- }
- signed main() {
- #ifdef _DEBUG
- freopen("input.txt", "r", stdin);
- #else
- std::ios::sync_with_stdio(false);
- cin.tie(0);
- #endif
- pows[0] = 1;
- for (int i = 1; i < N; i++) {
- pows[i] = (q * pows[i - 1]) % MOD;
- }
- cin >> n >> m >> q1;
- for (int i = 0; i < m; i++) {
- cin >> a[i];
- }
- for (int i = 0; i < n; i++) {
- cin >> b[i];
- }
- for (int i = m - 1; i >= 0; i--) {
- if (i + q1 >= m) {
- }
- else {
- fwd[i] = fwd[i + q1];
- fwd[i].push_front((a[i] - a[i + q1] + M) % M);
- }
- }
- for (int i = n - 1; i >= 0; i--) {
- if (i + q1 >= n) {
- }
- else {
- fwd2[i] = fwd2[i + q1];
- fwd2[i].push_front((b[i] - b[i+q1] + M) % M);
- if (fwd2[i].len >= m / q1) {
- int i1 = i + q1 * (fwd2[i].len - 1);
- fwd2[i].pop_back((b[i1] - b[i1 + q1] + M) % M);
- }
- }
- }
- s.clear();
- for (int i = 0; i < q1; i++) {
- s.push_back(fwd[i].hsh);
- }
- int ln = s.size() + 1;
- s.push_back(-1);
- for (int i = 0; i < n; i++) {
- s.push_back(fwd2[i].hsh);
- }
- zfun();
- for (int i = ln; i < s.size(); i++) {
- if (z[i] >= q1) {
- good[i - ln] = 1;
- //cout << i - ln << " ";
- }
- }
- s.clear();
- for (int i = 0; i < q1; i++) {
- s.push_back(a[i]);
- }
- s.push_back(-1);
- for (int i = 0; i < n; i++) {
- if (i - q1 >= 0) {
- s.push_back((b[i] - b[i - q1] + M) % M);
- }
- else {
- s.push_back(-1);
- }
- }
- zfun();
- for (int i = ln; i < s.size(); i++) {
- if (z[i] >= q1) {
- good[i - ln] &= 1;
- }
- else {
- good[i - ln] = 0;
- }
- }
- for (int i = q1; i < n; i++) {
- if (good[i]) {
- cout << i - q1 + 1;
- return 0;
- }
- }
- cout << -1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement