【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] ...
随机推荐
- 启用aspnet
1. 进入dotnetfw目录 cd C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 2. aspnet_regiis -i -enable
- hbuilder用自己的服务
2016-03-10 以后写测试demo用Sublime3 http://docs.emmet.io/cheat-sheet/ 更多炫酷信息和emmet语法请参见: 视频demo 语法文档 2016- ...
- Mysql 的一些异常解决
一.关于大文件存储 1.利用mysql存储大文件时,异常截图 在配置文件中加上如下一行 2.改完后重启mysql,但是又报如下错误: 解决方案: 我的mysql 是5.6版本,查到网上说要修改配置文件 ...
- 20160331javaweb 之JSP page 指令
- Touch事件or手机卫士面试题整理回答(二)
Touch事件or手机卫士面试题整理回答(二) 自定义控件 1. Touch事件的传递机制 顶级View->父View->子View,不处理逆向返回 OnInterceptTouchEve ...
- 将Excel,ppt和word转化为html
有些时候可能需要将Excel,ppt和word转化为html在页面上显示.我从网上查到一些代码,记录在这里以供需要的朋友参考 1.将word转化为html显示 //================== ...
- dynamic关键字
public class TestClass { public dynamic Values { get; set; } } public class Test { static void Func( ...
- OC加强-day05
#program mark - 0_11 NSRange结构体介绍 [掌握] 是Foundation框架中的一个结构体 NSRange 定义的一个变量的两个属性 location:起始下标 lengt ...
- swift-08-元组分解和数组
//1.有时候需要把元组中的数据拆分出来使用比如: var stu = ("范冰冰",30,"女") // 1)将stu中的数据赋值给三个变量. var (na ...
- Fibonacci数列的java实现
关于Fibonacci应该都比较熟悉,0,1,1,2,3..... 基本公式为f(n) = f(n-1) + f(n-2); f(0) = 0; f(1) =1; 方法1:可以运用迭代的方法实现: p ...