Cow Patterns
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 3156 | Accepted: 1167 |
Description
A particular subgroup of K (1 <= K <= 25,000) of Farmer John's cows likes to make trouble. When placed in a line, these troublemakers stand together in a particular order. In order to locate these troublemakers, FJ has lined up his N (1 <= N <= 100,000) cows. The cows will file past FJ into the barn, staying in order. FJ needs your help to locate suspicious blocks of K cows within this line that might potentially be the troublemaking cows.
FJ distinguishes his cows by the number of spots 1..S on each cow's coat (1 <= S <= 25). While not a perfect method, it serves his purposes. FJ does not remember the exact number of spots on each cow in the subgroup of troublemakers. He can, however, remember which cows in the group have the same number of spots, and which of any pair of cows has more spots (if the spot counts differ). He describes such a pattern with a sequence of K ranks in the range 1..S. For example, consider this sequence:
If the true count of spots for some sequence of cows is:
Please help FJ locate all the length-K subsequences in his line of cows that match his specified pattern.
FJ distinguishes his cows by the number of spots 1..S on each cow's coat (1 <= S <= 25). While not a perfect method, it serves his purposes. FJ does not remember the exact number of spots on each cow in the subgroup of troublemakers. He can, however, remember which cows in the group have the same number of spots, and which of any pair of cows has more spots (if the spot counts differ). He describes such a pattern with a sequence of K ranks in the range 1..S. For example, consider this sequence:
1 4 4 3 2 1In this example, FJ is seeking a consecutive sequence of 6 cows from among his N cows in a line. Cows #1 and #6 in this sequence have the same number of spots (although this number is not necessarily 1) and they have the smallest number of spots of cows #1..#6 (since they are labeled as '1'). Cow #5 has the second-smallest number of spots, different from all the other cows #1..#6. Cows #2 and #3 have the same number of spots, and this number is the largest of all cows #1..#6.
If the true count of spots for some sequence of cows is:
5 6 2 10 10 7 3 2 9then only the subsequence 2 10 10 7 3 2 matches FJ's pattern above.
Please help FJ locate all the length-K subsequences in his line of cows that match his specified pattern.
Input
Line 1: Three space-separated integers: N, K, and S
Lines 2..N+1: Line i+1 describes the number of spots on cow i.
Lines N+2..N+K+1: Line i+N+1 describes pattern-rank slot i.
Lines 2..N+1: Line i+1 describes the number of spots on cow i.
Lines N+2..N+K+1: Line i+N+1 describes pattern-rank slot i.
Output
Line 1: The number of indices, B, at which the pattern matches
Lines 2..B+1: An index (in the range 1..N) of the starting location where the pattern matches.
Lines 2..B+1: An index (in the range 1..N) of the starting location where the pattern matches.
Sample Input
9 6 10 5 6 2 10 10 7 3 2 9 1 4 4 3 2 1
Sample Output
1 3
Hint
Explanation of the sample:
The sample input corresponds to the example given in the problem statement.
There is only one match, at position 3 within FJ's sequence of N cows.
The sample input corresponds to the example given in the problem statement.
There is only one match, at position 3 within FJ's sequence of N cows.
Source
解题思路:模式串和子串中对应的位置数的大小在两个串中一致,则两个串匹配,两个串匹配就是各自串中小于对应位置的数的数字数目相等,等于对应位置的数的数字的数目也相等,用A[i][j],B[i][j]两个数组分别预处理出原串和模式串中到第i位位置数字j出现的次数,然后就和普通的KMP是一样的了
#include <iostream>
#include <cstdio>
#include <cstring>
#define M 30000
#define N 100005
using namespace std;
int A[N][30],B[M][30],a[N],b[M],arr[N];
void get_next(int *next,int m)
{
int i,j=1,k=0;
next[1]=0;
while(j<=m)
{
int si=0,sj=0,ei=0,ej=0;
for(i=1;i<b[j];i++)
si+=B[j][i]-B[j-k][i];
ei=B[j][i]-B[j-k][i];
for(i=1;i<b[k];i++)
sj+=B[k][i];
ej=B[k][i];
if(k==0||si==sj&&ei==ej)
{
j++;k++;
next[j]=k;
}
else
k=next[k];
}
}
int kmp(int m,int n)
{
int *next=new int[m+5];
get_next(next,m);
int i=1,j=1,k,ans=0;
while(i<=n)
{
int si=0,sj=0,ei=0,ej=0;
for(k=1;k<a[i];k++)
si+=A[i][k]-A[i-j][k];
ei=A[i][k]-A[i-j][k];
for(k=1;k<b[j];k++)
sj+=B[j][k];
ej=B[j][k];
if(j==0||si==sj&&ei==ej)
i++,j++;
else
j=next[j];
if(j>m)
{
arr[ans++]=i-j+1;
j=next[j];
}
}
return ans;
}
int main()
{
int i,n,k,s,ans;
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(~scanf("%d%d%d",&n,&k,&s))
{
memset(A,0,sizeof(A));
memset(B,0,sizeof(B));
for(i=1;i<=n;i++)
{
scanf("%d",a+i);
A[1][a[1]]=1;
if(i>1)
memcpy(A[i],A[i-1],sizeof(A[0]));
A[i][a[i]]++;
}
for(i=1;i<=k;i++)
{
scanf("%d",b+i);
B[1][b[1]]=1;
if(i>1)
memcpy(B[i],B[i-1],sizeof(B[0]));
B[i][b[i]]++;
}
printf("%d\n",ans=kmp(k,n));
for(i=0;i<ans;i++)
printf("%d\n",arr[i]);
}
return 0;
}