【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] ...
随机推荐
- JS调用ashx文件传递中文参数取不到值的解决方案
引自:http://www.cnblogs.com/yinpeng186/archive/2011/09/30/2196726.html
- XML序列化/反序列化数据库形式保存和读取。
直接上码: 首先创建class1类 public class Class1 { public string name { get; set; } public int age { get; set; ...
- Quartz Cron表达式生成器
格式: [秒] [分] [小时] [日] [月] [周] [年] 序号 说明 是否必填 允许填写的值 允许的通配符 1 秒 是 0-59 , - * / 2 分 是 0 ...
- netMVC 搭建Ucenter 同步登陆退出discuz
先看一下效果
- 20151210 Jquery 学习笔记 AJAX 进阶
一.加载请求 在 Ajax 异步发送请求时,遇到网速较慢的情况,就会出现请求时间较长的问题.而超 过一定时间的请求,用户就会变得不再耐烦而关闭页面.而如果在请求期间能给用户一些提 示,比如:正在努力加 ...
- C# 自定义排序
/// <summary> /// 实体 /// </summary> public class Product { public int ID { get; set; } p ...
- Help View修复
好吧,手贱把ProgramData里关于Help View的某些数据删除了 (在任何情况下都不要删除此文件夹中的任何数据).即使卸载后重新安装也出现错误,可以参考的http://social.msdn ...
- SQL语句一点小心得
在Sqlserver中 if 语句后面的语句加begin end 括起来 问题:执行速度问题,在存储过程中没有加begin end 执行速度很慢,加了begin end执行速度加快 ALTER PRO ...
- iOS 高级开发 runtime(三)
三 .动态添加方法 我们可以通过runtime动态地添加方法.那么到底啥叫动态添加方法呢?动态添加方法就是当我们程序运行时才知道我们应该调用哪个方法.我们首先需要了解这一点,当我们编写完一段代码后,我 ...
- Nginx的反向代理
先通过简单的图来说明一下正向代理和反向代理吧~ 正向代理 代理其实就是一个中介,A和B本来可以直连,中间插入一个C,C就是中介.刚开始的时候,代理多数是帮助内网client访问外网server用的(比 ...