【POJ 3167】Cow Patterns (KMP+树状数组)
Cow PatternsDescription
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 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 SLines 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 matchesLines 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
1Sample Output
1
3Hint
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+树状数组)的更多相关文章
- 【bzoj2384】[Ceoi2011]Match 特殊匹配条件的KMP+树状数组
题目描述 给出两个长度分别为n.m的序列A.B,求出B的所有长度为n的连续子序列(子串),满足:序列中第i小的数在序列的Ai位置. 输入 第一行包含两个整数n, m (2≤n≤m≤1000000). ...
- POJ 2182 Lost Cows 【树状数组+二分】
题目链接:http://poj.org/problem?id=2182 Lost Cows Time Limit: 1000MS Memory Limit: 65536K Total Submis ...
- poj 3321:Apple Tree(树状数组,提高题)
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 18623 Accepted: 5629 Descr ...
- POJ 2299 Ultra-QuickSort 逆序数 树状数组 归并排序 线段树
题目链接:http://poj.org/problem?id=2299 求逆序数的经典题,求逆序数可用树状数组,归并排序,线段树求解,本文给出树状数组,归并排序,线段树的解法. 归并排序: #incl ...
- poj 3321 Apple Tree(一维树状数组)
题目:http://poj.org/problem?id=3321 题意: 苹果树上n个分叉,Q是询问,C是改变状态.... 开始的处理比较难,参考了一下大神的思路,构图成邻接表 并 用DFS编号 白 ...
- POJ 2299 Ultra-QuickSort 离散化加树状数组求逆序对
http://poj.org/problem?id=2299 题意:求逆序对 题解:用树状数组.每读入一个数x,另a[x]=1.那么a数列的前缀和s[x]即为x前面(或者说,再x之前读入)小于x的个数 ...
- luoguP4696 [CEOI2011]Matching KMP+树状数组
可以非常轻易的将题意转化为有多少子串满足排名相同 注意到$KMP$算法只会在当前字符串的某尾添加和删除字符 因此,如果添加和删除后面的字符对于前面的字符没有影响时,我们可以用$KMP$来模糊匹配 对于 ...
- 【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 ...
- POJ 3378 Crazy Thairs(树状数组+DP)
[题目链接] http://poj.org/problem?id=3378 [题目大意] 给出一个序列,求序列中长度等于5的LIS数量. [题解] 我们发现对于每个数长度为k的LIS有dp[k][i] ...
随机推荐
- 搭建FTP+PAM+MySQL环境
搭建FTP+PAM+MySQL环境 1 搭建环境: CentOS6.5或CentOS6.7 [root@vhost3 ~]# uname -a Linux vhost3 -.el6.x86_64 # ...
- 百度编辑器umeditor使用总结
百度编辑器是一个功能很全.很强大. 百度单张图片上传只能存储在项目下面,而不能独立自定义存储位置,因此重写上传代码 百度文章中的图片是通过base64实现的,直接存储在数据库中 tomcat通过虚拟路 ...
- MVC中HtmlHelper用法大全参考
MVC中HtmlHelper用法大全参考 解析MVC中HtmlHelper控件7个大类中各个控件的主要使用方法(1) 2012-02-27 16:25 HtmlHelper类在命令System.Web ...
- Android开发5大布局方式详解
Android中常用的5大布局方式有以下几种: 线性布局(LinearLayout):按照垂直或者水平方向布局的组件. 帧布局(FrameLayout):组件从屏幕左上方布局组件. 表格布局(Tabl ...
- 【C#】获取本地Cookie的问题
using System; using System.Net; using System.IO; using System.Text; // // TODO: 在此处添加代码以启动应用程序 // st ...
- iOS-开发日志-UIButton
UIButton属性 1.UIButton状态: UIControlStateNormal // 正常状态 UIControlStateHighlighted // 高 ...
- html-----016---HTTP 状态消息
HTTP 状态消息 当浏览器从 web 服务器请求服务时,可能会发生错误. 从而有可能会返回下面的一系列状态消息: 1xx: 信息 消息: 描述: 100 Continue 服务器仅接收到部分请求,但 ...
- CSS背景属性
CSS背景属性 1.background-attachment 属性 scroll:默认值.背景图像会随着页面其余部分的滚动而移动. fixed:当页面的其余部分滚动时,背景图像不会移动. inher ...
- 15_AOP入门准备_静态代理模式
[工程截图] [PersonDao.java] package com.HigginCui.daoProxy; public interface PersonDao { public void sav ...
- C++类继承内存布局(二)
转自:http://blog.csdn.net/jiangyi711/article/details/4890889# (二 )成员变量 前面介绍完了类布局,接下来考虑不同的继承方式下,访问成员变量的 ...