博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj 3167(KMP+树状数组)
阅读量:6869 次
发布时间:2019-06-26

本文共 4461 字,大约阅读时间需要 14 分钟。

之前自己在做题的时候在网上找别人的题解,虽然当时理解,但时间一久就忘了。所以开个这个东西来记录自己的学习进程,方便自己的回顾,以及给他人提供题解。
 
开始冲击明年高二的省选!不再颓废!
 
好了,下面进入正题
 
 
 
Cow Patterns
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 3144   Accepted: 1164

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 1056210107329144321

Sample Output

13

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.

 

 

题目大意:

稍稍神奇的KMP。

模式串和匹配串匹配的条件是:匹配串各个位置数字的大小关系与模式串相同。或者说:把匹配串离散化后与模式串相同。

 

思路:

在普通的KMP中,当时s[i..j]和t[k..l]已经匹配时,s[i..j+1]和t[k..l+1]匹配的条件是s[j+1]=t[l+1];而在本题中,要求匹配串各个位置数字的大小关系与模式串相同,

那么s[i..j+1]和t[k..l+1]匹配的条件便是s[i..j+1]中小于(等于)s[j+1]的数的个数与t[k..l]中小于(等于)t[l+1]的数的个数相同。用一个树状数组来记录s[i..j]/t[k..l]中小于(等于)

s[j+1]/t[l+1]的数的个数即可

其他与普通KMP基本相同。

 

#include
#include
#include
#include
#include
using namespace std;int m1[100011],m2[100011],next[100011];int a[100011],b[100011],ans[100011],f[101];int n,m,t,i,j,xzq,x;int lowbit(int x){ return x&-x;}int get(int k){ int l; l=0; while(k>0){ l+=f[k]; k-=lowbit(k); } return l;}void add(int k,int v){ while(k<=t){ f[k]+=v; k+=lowbit(k); }}int main(){ scanf("%d%d%d",&m,&n,&t); for(i=1;i<=m;i++)scanf("%d",&b[i]); for(i=1;i<=n;i++)scanf("%d",&a[i]); for(i=1;i<=n;i++){ m1[i]=get(a[i]-1); m2[i]=get(a[i])-m1[i]; add(a[i],1); } memset(f,0,sizeof(f)); x=0; for(i=2;i<=n;i++){ while(x!=0&&(get(a[i]-1)!=m1[x+1]||get(a[i])-get(a[i]-1)!=m2[x+1])){ for(j=i-x;j<=i-1-next[x];j++)add(a[j],-1); x=next[x]; } if(get(a[i]-1)==m1[x+1]&&get(a[i])-get(a[i]-1)==m2[x+1]){ add(a[i],1); x++; } next[i]=x; } x=0; memset(f,0,sizeof(f)); for(i=1;i<=m;i++){ while(x!=0&&(get(b[i]-1)!=m1[x+1]||get(b[i])-get(b[i]-1)!=m2[x+1])){ for(j=i-x;j<=i-1-next[x];j++)add(b[j],-1); x=next[x]; } if(get(b[i]-1)==m1[x+1]&&get(b[i])-get(b[i]-1)==m2[x+1]){ add(b[i],1); x++; } if(x==n){ ans[++xzq]=i-n+1; for(j=i-x+1;j<=i-next[x];j++)add(b[j],-1); x=next[x]; } } printf("%d\n",xzq); for(i=1;i<=xzq;i++)printf("%d\n",ans[i]);}

 

 

转载于:https://www.cnblogs.com/applejxt/p/3801458.html

你可能感兴趣的文章
Axios使用说明
查看>>
未加入域的Windows 7+outlook 2010连接Exchange 2013经常弹出用户名和密码
查看>>
如何利用多核CPU来加速你的Linux命令 — awk, sed, bzip2, grep, wc等
查看>>
分布式服务框架 Zookeeper -- 管理分布式环境中的数据(转)
查看>>
Android7.1Shortcuts
查看>>
Java面试题
查看>>
Spark GraphX之全局聚类系数、局部聚类系数、网络平均聚类系数
查看>>
oracle排序操作
查看>>
我的友情链接
查看>>
4-4高项作业
查看>>
JPA常用注解
查看>>
Git使用详细教程
查看>>
我的友情链接
查看>>
Maven学习总结(六)——Maven与Eclipse整合
查看>>
Java基础学习总结(14)——Java对象的序列化和反序列化
查看>>
vmware中centos6.7系统图形化安装Oracle-无法打开RUNINSTALLER
查看>>
设计模式(十三)——享元模式
查看>>
jQuery零基础开发之富客户端应用
查看>>
linux系统内核UDP丢包原因分析
查看>>
Maven学习总结(七)——eclipse中使用Maven创建Web项目
查看>>