Cow Patterns

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:

      1 4 4 3 2 1

In 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 9

then 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.

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.

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.

 
 
 
【题意】
  

  给定一个模式串,如果在主串中存在这样一个子串:子串长度与模式串长度相同,且子串中各个数字的大、小、同关系和模式串中的大、小、同关系是一样的,就称该子串满足条件。

  比如说模式串:1,4,4,2,3,1 而主串:5,6,2,10,10,7,3,2,9

  那么主串第三位开始的2,10,10,7,3,2就是满足条件的。(即两个子串离散值相等则为相等)

【分析】

  如果单纯判断字母串相等,这题可以用普通的KMP做,但是这里重新定义了相等,我们就要在原的KMP中修改一下。

  两个子串相等,当且仅当其离散值相等。

  

  如图,假设我们已经判断粉框内子串完全相等,我们现在判断各新加一个元素后是否相等:

  只要判断->A串中小于新元素的数字个数 等于 B串中小于新元素的数字个数

  且 A串中等于新元素的数字个数 等于 B串中等于新元素的数字个数 即可。(想一下 离散值 相等 就知道了)

  所以,只要在较快时间内求出区间小于数k的元素个数即可。

  对于A串,我们可以发现粉框的左端是不断向右移的,所以可以用权值树状数组动态维护。

  那个...粉框左端不断向右移,今天才发现~~KMP没学透吧...

代码如下:

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define Maxn 100010
#define Maxk 25010 int n,k,s;
int a[Maxn],b[Maxk],rk[Maxk],sm[Maxk];
int c[];
int nt[Maxk],td[Maxn]; struct node
{
int x,id;
}t[Maxk]; bool cmp(node x,node y) {return x.x<y.x;} void add(int x,int y)
{
for(int i=x;i<=;i+=i&(-i))
c[i]+=y;
} int gsum(int x)
{
int ans=;
for(int i=x;i>=;i-=i&(-i))
{
ans+=c[i];
}
return ans;
} void init()
{
scanf("%d%d%d",&n,&k,&s);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
for(int i=;i<=k;i++) {scanf("%d",&t[i].x);t[i].id=i;}
sort(t+,t++k,cmp); int p=;b[t[].id]=;
for(int i=;i<=k;i++)
{
if(t[i].x!=t[i-].x) p++;
b[t[i].id]=p;
} memset(c,,sizeof(c));
for(int i=;i<=k;i++)
{
rk[i]=gsum(b[i]-);//less than b[i]
sm[i]=gsum(b[i]);//less or the same as b[i]
add(b[i],);
}
memset(c,,sizeof(c));
} void kmp()
{
nt[]=;
int p=;
for(int i=;i<=k;i++)
{
while((gsum(b[i]-)!=rk[p+]||gsum(b[i])!=sm[p+])&&p)
{
for(int j=i-p;j<=i-nt[p]-;j++) add(b[j],-);
p=nt[p];
}
if(gsum(b[i]-)==rk[p+]&&gsum(b[i])==sm[p+]) p++;
nt[i]=p;
add(b[i],);
} memset(c,,sizeof(c));
p=;
for(int i=;i<=n;i++)
{
while(((gsum(a[i]-)!=rk[p+]||gsum(a[i])!=sm[p+])&&p)||p==k)
{
for(int j=i-p;j<=i-nt[p]-;j++) add(a[j],-);
p=nt[p];
}
if(gsum(a[i]-)==rk[p+]&&gsum(a[i])==sm[p+]) p++;
td[i]=p;
add(a[i],);
}
} int pri[Maxn];
void ffind()
{
int ans=;
for(int i=;i<=n;i++) if(td[i]==k)
{
pri[++ans]=i-k+;
}
printf("%d\n",ans);
for(int i=;i<=ans;i++) printf("%d\n",pri[i]);
} int main()
{
init();
kmp();
ffind();
return ;
}

[POJ3167]

2016-08-07 14:38:40

【POJ 3167】Cow Patterns (KMP+树状数组)的更多相关文章

  1. 【bzoj2384】[Ceoi2011]Match 特殊匹配条件的KMP+树状数组

    题目描述 给出两个长度分别为n.m的序列A.B,求出B的所有长度为n的连续子序列(子串),满足:序列中第i小的数在序列的Ai位置. 输入 第一行包含两个整数n, m (2≤n≤m≤1000000).  ...

  2. POJ 2182 Lost Cows 【树状数组+二分】

    题目链接:http://poj.org/problem?id=2182 Lost Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submis ...

  3. poj 3321:Apple Tree(树状数组,提高题)

    Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18623   Accepted: 5629 Descr ...

  4. POJ 2299 Ultra-QuickSort 逆序数 树状数组 归并排序 线段树

    题目链接:http://poj.org/problem?id=2299 求逆序数的经典题,求逆序数可用树状数组,归并排序,线段树求解,本文给出树状数组,归并排序,线段树的解法. 归并排序: #incl ...

  5. poj 3321 Apple Tree(一维树状数组)

    题目:http://poj.org/problem?id=3321 题意: 苹果树上n个分叉,Q是询问,C是改变状态.... 开始的处理比较难,参考了一下大神的思路,构图成邻接表 并 用DFS编号 白 ...

  6. POJ 2299 Ultra-QuickSort 离散化加树状数组求逆序对

    http://poj.org/problem?id=2299 题意:求逆序对 题解:用树状数组.每读入一个数x,另a[x]=1.那么a数列的前缀和s[x]即为x前面(或者说,再x之前读入)小于x的个数 ...

  7. luoguP4696 [CEOI2011]Matching KMP+树状数组

    可以非常轻易的将题意转化为有多少子串满足排名相同 注意到$KMP$算法只会在当前字符串的某尾添加和删除字符 因此,如果添加和删除后面的字符对于前面的字符没有影响时,我们可以用$KMP$来模糊匹配 对于 ...

  8. 【bzoj2274】[Usaco2011 Feb]Generic Cow Protests dp+树状数组

    题目描述 Farmer John's N (1 <= N <= 100,000) cows are lined up in a row andnumbered 1..N. The cows ...

  9. POJ 3378 Crazy Thairs(树状数组+DP)

    [题目链接] http://poj.org/problem?id=3378 [题目大意] 给出一个序列,求序列中长度等于5的LIS数量. [题解] 我们发现对于每个数长度为k的LIS有dp[k][i] ...

随机推荐

  1. 转:what is TWO_TASK

    https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:89412348059 You Asked what is t ...

  2. verilog语法:进程名

    always @ (posedge clk, negedge rstn)begin:State_flipflops if(!rstn) y<=S1; else y<=Y;end请问这段程序 ...

  3. c#调用c++ dll(一)

    首先来说说c++中的dll 核心的一些知识 比较大的应用程序都由很多模块组成,这些模块分别完成相对独立的功能,它们彼此协作来完成整个软件系统的工作.可能存在一些模块的功能较为通用,在构造其它软件系统时 ...

  4. [转] c# 数据类型占用的字节数

    http://www.cnblogs.com/laozuan/archive/2012/04/24/2467888.html

  5. 那天有个小孩跟我说LINQ(四)转载

    1  LINQ TO SQL(代码下载)       我们以一个酒店管理系统的数据库为例子         表结构很简单:GuestInfo(客人信息表),Room(房间表),RoomType(房间类 ...

  6. Power Map 更新日志

    2015-05-18,五月更新 Custom Regions feature,允许用户自定义区域要素,支持kml和shape格式 New customization features,包括图例/文本框 ...

  7. 01_JavaMail_05_创建邮件工具类MailUtils等方便发送邮件

    [工程截图] [代码实现] [Mail.java] package com.Higgin.Utils; import java.util.ArrayList; import java.util.Lis ...

  8. HDU_2156 分数矩阵

    Problem Description             我们定义如下矩阵:            1/1 1/2 1/3            1/2 1/1 1/2            1 ...

  9. libsdl中文输入法候选列表不显示解决方案

    libsdl输入中文时输入法不显示,将WM_IME_SETCONTEXT事件处理给注释即可. WM_IME_SETCONTEXT If the application draws the compos ...

  10. 虚拟机中如何Linux系统如何访问PC硬盘中的文件(如何将windows下的文件夹挂载到linux虚拟机下)

    这段时间决定学习嵌入式,变打算安装个Linux系统先熟悉一下Linux系统的使用,但自己电脑上安装的win7系统又不想装双系统,一是闲麻烦,二是由于对Linux系统不熟悉担心会因为自己的误操作而损坏系 ...