canuc80k1910·11/50

Mẫu Cao Độ Dịch Chuyển

Nộp bài trên LQDOJ

Bài 1.10 · Hashing

Cho hai dãy số nguyên gồm phần tử và gồm phần tử.

Một đoạn liên tiếp được gọi là khớp với nếu tồn tại một số nguyên sao cho

với mọi từ đến . Số được phép âm, bằng hoặc dương, và có thể khác nhau giữa các đoạn.

Hãy đếm số vị trí bắt đầu tạo thành một đoạn khớp. Nếu thì không có vị trí nào hợp lệ. Đặc biệt, khi , mọi phần tử của đều tạo thành một đoạn khớp.

Input

  • Dòng đầu chứa hai số nguyên và .
  • Dòng thứ hai chứa số nguyên .
  • Dòng thứ ba chứa số nguyên .

Output

  • In một số nguyên: số đoạn liên tiếp của khớp với .

Constraints

  • .
  • .

Scoring

  • Subtask ( số điểm): .
  • Subtask ( số điểm): Không có giới hạn bổ sung.

Example

Test 1

Input

8 3
5 7 8 2 4 5 10 12
1 3 4

Output

2

Giải thích: Đoạn bắt đầu tại là , thu được khi cộng vào mọi phần tử của . Đoạn bắt đầu tại là , tương ứng với độ dịch ; không có vị trí bắt đầu nào khác thỏa mãn.

Lời giải tóm tắt
  • Ý tưởng: Nếu cộng cùng một số vào toàn bộ dãy b, mọi hiệu giữa hai phần tử liên tiếp của b đều giữ nguyên. Vì vậy một đoạn độ dài m của a khớp khi và chỉ khi dãy m-1 hiệu liên tiếp của đoạn đó bằng dãy hiệu của b.
  • Ý tưởng: Ta tạo da[i] = a[i+1]-a[i] và db[i] = b[i+1]-b[i], xây double rolling hash cho hai dãy hiệu rồi so hash của mọi cửa sổ dài m-1 trong da với hash của db. Trường hợp m=1 được xử lý riêng vì không có hiệu nào cần so; nếu m>n thì đáp án bằng 0.
  • Ý tưởng: Hai chiều của mệnh đề tương đương đều đúng: phép dịch không đổi hiệu; ngược lại, nếu mọi hiệu bằng nhau thì chọn x=a[l]-b[0] và suy ra lần lượt mọi phần tử còn lại cũng bằng nhau sau dịch.
  • Ý tưởng: Độ phức tạp: O(n+m) thời gian và O(n+m) bộ nhớ.