Sereja has two sequences a and b and number p. Sequence a consists of n integers a1, a2, ..., an. Similarly, sequence b consists of m integers b1, b2, ..., bm. As usual, Sereja studies the sequences he has. Today he wants to find the number of positions q (q + (m - 1)·p ≤ n; q ≥ 1), such that sequence b can be obtained from sequence aq, aq + p, aq + 2p, ..., aq + (m - 1)p by rearranging elements.
Sereja needs to rush to the gym, so he asked to find all the described positions of q.
The first line contains three integers n, m and p (1 ≤ n, m ≤ 2·105, 1 ≤ p ≤ 2·105). The next line contains nintegers a1, a2, ..., an (1 ≤ ai ≤ 109). The next line contains m integers b1, b2, ..., bm (1 ≤ bi ≤ 109).
In the first line print the number of valid qs. In the second line, print the valid values in the increasing order.
5 3 1 1 2 3 2 1 1 2 3
2 1 3
6 3 2 1 3 2 2 3 1 1 2 3
21 2
题意:
题目要求在a 数组找和 b 数组等长的下标成等差数列的子序列。问等差数列首项 q 的可能的值。
思路:
如果不限定等差数列的长度,那么对于确定的 p , q 取值范围为1,2,3......p;现在限定等差子序列长度为m,则 q 可能为原等差数列的前几项。
所以 :
1.双层循环 外层 q 从1 到 p;内层 j 从 for(ll j = i; j <= n; j+=p) 注意用long long;
2.用队列先进先出的性质,依次存取子等差数列的值,存够m个值后,比较一下 队列里下标对应a[]的值与b[] 的数是否一致,具体方法见3,一致,则吐出队首的下标,q数目加1,不一致丢弃;
3 用 map 存关系,从而确定队列里存的下标确定的a[]里的值,是否能和b[]里一致,map 可以直接判断是否相等如mp1 == mp2,但是如果mp [x] == 0 了 记得mp.erase(x),否则影响mp1 == mp 的比较。
#include <map> #include <cstdio> #include <queue> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; const int maxn = 2e5 + 10; int a[maxn],b[maxn],ans[maxn]; map <int ,int> mpa,mpb; int main() { int n,m,p; scanf("%d%d%d",&n,&m,&p); for(int i = 1; i <= n ; i++) scanf("%d",&a[i]); for(int i = 1; i <= m; i++) { scanf("%d",&b[i]); mpb[b[i]] ++ ; } int k = 0; for(int i = 1; i <= p; i++) { queue <int > qu; mpa.clear(); for(ll j = i; j <= n; j += p) { mpa[a[j]] ++; qu.push(j); if(qu.size() == m) { int x = qu.front(); if(mpa == mpb) ans[k++] = x; qu.pop(); mpa[a[x]] --; if(mpa[a[x]] == 0) mpa.erase(a[x]); } } } sort(ans,ans+k); printf("%d\n",k); for(int i = 0; i < k; i++) printf("%d ",ans[i]); printf("\n"); }