VJ 【STL】

/*
Description
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.

Sample Input
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
*/ 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm> 
#include<map>
#include<queue>
using namespace std;

typedef map<int,int> MY;
MY B;
int a[220000], ans[220000];

int main()
{
	    int i, j, k, n, m, p;
		scanf("%d%d%d", &n, &m, &p);
	
		B.clear();
		for(i = 1; i <= n; ++i)
		scanf("%d", &a[i]);
		for(i = 1; i <= m; ++i)
		{
			scanf("%d", &k);
			B[k]++;
		}
		if(1+(m-1)*p > n)
		{
			printf("0\n");
			return 0;
		}
		k = 0;
		for(i = 1; i <= p; i++) //q
		{
			MY temp;//存取数字 
			deque<int> q;//存取编号 
			temp.clear();
		//	memset(vis,false,sizeof(vis));
			for(j = i; j <= n; j += p) //以i开头的间隔为p的数列 
			{
				q.push_back(j);
				temp[a[j]]++;
				if(q.size() > m)
				{
					int x = q.front();
					q.pop_front();
					temp[a[x]]--;
					if(temp[a[x]] == 0)
					temp.erase(a[x]); //清楚内存 
				}
				if(temp == B)
				{
					ans[k++] = q.front();
				}
			} 
		}
		
		sort(ans, ans+k);
		printf("%d\n", k);
		for(i = 0; i < k; ++i)
		{
			if(i)
			printf(" ");
			printf("%d", ans[i]);
		}
		printf("\n");
		return 0;
} 

//题意:给出2个数列,个一个数p,要求以第一个数列的某个数开始,每间隔p个数取一个数,组成一个长度和第二个数列一样长的数列,如果相同则保存第一个数在第一个数列中的位置
//思路:用一个容器模拟队列将以1-p为开头的每间隔p个数的数列保存起来。然后每当长度与第二个数列一样时比较2个容器,每多一个数进队列则删除队首 遍历结束即可 



此题如果用数组模拟队列也可以,但是在比较b和新数列时需要一个一个数进行比较,而这里用容器的话直接比较每个数的个数是否相同即可,如果用数组来保存每个数的数目在这里是无法实现的,因为每个数的范围过大,数组无法统计。

你可能感兴趣的:(VJ 【STL】)