您的位置:首页 > 其它

Sereja ans Anagrams(map)

2017-07-26 07:39 260 查看
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.


Input

The first line contains three integers n, m and p (1 ≤ n, m ≤ 2·105, 1 ≤ p ≤ 2·105). The next line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 109). The next line contains m integers b1, b2, ..., bm (1 ≤ bi ≤ 109).


Output

In the first line print the number of valid qs. In the second line, print the valid values in the increasing order.


Example

Input

5 3 1
1 2 3 2 1
1 2 3

Output

2
1 3

Input

6 3 2
1 3 2 2 3 1
1 2 3

Output

2
1 2


还是模拟的思想,我们遍历所有能做起点的点,然后取数,当我们的数量等于目标序列的数量的时候,我们进行比较,可以的话,我们的总和就加1。

为了节省时间,我们都是一次+p+p+…直接到底,下次就不用再去把这些点当做起点了。

#include <cstdio>
#include <cstring>
#include<algorithm>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;//不能只看n,m,p的范围,还要看他们的运算,题目中又有乘法,所以我们必须要ll
const int Max=2e5+10;
//这个题用map 的好处是什么,就是可以直接进行判断是不是想等,想一下,两个大数组直接一个等号,多么简单
//只不过,map就算里面的值等于0了,他也不会自动删除,需要我们手动来完成
int answer[Max];
int a[Max];
int vis[Max];
map<int,int> mp;
map<int,int> TM;
int main()
{
memset(vis,0,sizeof(vis));
ll n,m,p;
scanf("%I64d%I64d%I64d",&n,&m,&p);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int x;
for(int i=1;i<=m;i++)
scanf("%d",&x),mp[x]++;//运算符重载[],可以直接当成数组用
int ans=0;
for(int i=1;i<=n&&i+(m-1)*p<=n;i++)
{
if(vis[i])//因为我们拿来一个点就直接m m m到底了,所以说一个数一旦被标记,他的所有可能性都尝试了
continue;
queue<int> q;//队列的目的,一个就是看数量,在一个就是先进先出的特点
TM.clear();
for(int j=i;j<=n;j+=p)
{
q.push(j);
vis[j]=1;
TM[a[j]]++;
if(q.size()==m)
{
if(TM==mp)
{
answer[ans]=q.front();
ans++;
}
//因为序列是连续的,所以我们可以去掉第一个点,看后面还能不能组成目标序列
int x=q.front();
q.pop();
TM[a[x]]--;//把临时地图中相应位置的数减一
//如果这点的数量已经为空了,但是这个节点还会有,我们需要清空它
if(!TM[a[x]])
TM.erase(a[x]);//也是相当于下标
}
}
}
printf("%d\n",ans);
sort(answer,answer+ans);
for(int i=0;i<ans;i++)
printf("%d ",answer[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  stl