BZOJ 1729: [Usaco2005 dec]Cow Patterns 牛的模式匹配

Description

约翰的N(1≤N≤100000)只奶牛中出现了K(1≤K≤25000)只爱惹麻烦的坏蛋.奶牛们按一定的顺序排队的时候,这些坏蛋总会站在一起.为了找出这些坏蛋,约翰让他的奶牛排好队进入牛棚,同时需要你的慧眼来识别坏蛋,为了区分,约翰给所有奶牛都发了号牌,上面写着一个1..S(1≤S≤25)之间的数字.虽然这不是一个完美的方法,但也能起一点作用.现在,约翰已经不记得坏蛋们的具体号码.但是凭他的记忆,他给出一个“模式串”.原坏蛋的号码如果相同,模式串中他们的号码依然相同.模式串中坏蛋们之间号码的大小关系也与原号码相同的.比如,对于这样一个模式串:1,4,4,3,,2,1 。原来的6只坏蛋,排最前面的与排最后的号码相同(尽管不一定是1),而且他们的号码在团伙中是最小的.第2,3位置的坏蛋,他们的号码也相同(不一定是4),且是坏蛋团伙中最大的.    现在所有奶牛排成队列,号码依次是这样:    5,6,2,10,10,7,3,2,9存在子串2,10,10,7,3,2,满足模式串的相同关系和大小关系,所以这就是坏蛋团伙, 请找出K个坏蛋的困伙的所有可能性.

Input

第1行输入三个整数N,K,S.接下来N行每行输入一只牛的号码.接下来K行每行输入一个模式串的号码.

Output

第1行输出一个整数B.接下来B行,每行一个整数,表示一种可能下的坏蛋团伙的起始位置.

题解:

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>

//by zrt
//problem:
using namespace std;
typedef long long LL;
const int inf(0x3f3f3f3f);
const double eps(1e-9);
int n,k,s;int aa[100005][26],bb[100005][26];int a[100005],b[100005];
bool cmp(int j,int i,int c1,int c2){//b 0...j | a i-j..i
    int sum1=0,sum2=0;
    for(int k=1;k<c1;k++){
        sum1+=j?bb[j-1][k]:0;
    }
    for(int k=1;k<c2;k++){
        sum2+=(i?aa[i-1][k]:0)-((i-j)?aa[i-j-1][k]:0);
    }
    return sum1==sum2&&(j?bb[j-1][c1]:0)==((i?aa[i-1][c2]:0)-((i-j)?aa[i-j-1][c2]:0));
}
bool cmpp(int j,int i,int c1,int c2){//b 0...j |b i-j..i
    int sum1=0,sum2=0;
    for(int k=1;k<c1;k++){
        sum1+=j?bb[j-1][k]:0;
    }
    for(int k=1;k<c2;k++){
        sum2+=(i?bb[i-1][k]:0)-((i-j)?bb[i-j-1][k]:0);
    }
    return sum1==sum2&&(j?bb[j-1][c1]:0)==((i?bb[i-1][c2]:0)-((i-j)?bb[i-j-1][c2]:0));
}
int nxt[100005];

void mk_pre(){
    for(int i=0;i<n;i++) {
        if(i)for(int j=1;j<=s;j++) aa[i][j]=aa[i-1][j];
        aa[i][a[i]]++;
    }
    for(int i=0;i<k;i++) {
        if(i)for(int j=1;j<=s;j++) bb[i][j]=bb[i-1][j];
        bb[i][b[i]]++;
    }
}
void mk(){
    int j=-1;
    nxt[0]=-1;
    for(int i=1;i<k;i++){
        while(~j&&!cmpp(j+1,i,b[j+1],b[i])) j=nxt[j];
        if(cmpp(j+1,i,b[j+1],b[i])) j++;
        nxt[i]=j;
    }
}

int ans[100005],top;
int main(){
    #ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    scanf("%d%d%d",&n,&k,&s);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    for(int i=0;i<k;i++){
        scanf("%d",&b[i]);
    }
    mk_pre();// qianzhuihe
    mk();
    int j=-1;
    for(int i=0;i<n;i++){
        while(~j&&!cmp(j+1,i,b[j+1],a[i])) j=nxt[j];
        if(cmp(j+1,i,b[j+1],a[i])) j++;
        if(j==k-1){
            ans[top++]=i-j+1;
            j=nxt[j];
        }
    }
    printf("%d\n",top);
    for(int i=0;i<top;i++){
        printf("%d\n",ans[i]);
    }
    return 0;
}
时间: 2024-12-18 09:24:08

BZOJ 1729: [Usaco2005 dec]Cow Patterns 牛的模式匹配的相关文章

BZOJ 1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚

题目 1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚 Time Limit: 5 Sec  Memory Limit: 64 MB Description Farmer John's cows, pampered since birth, have reached new heights of fastidiousness. They now require their barn to be immaculate. Farmer John, the most

BZOJ 3390: [Usaco2004 Dec]Bad Cowtractors牛的报复

题目 3390: [Usaco2004 Dec]Bad Cowtractors牛的报复 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 53  Solved: 37[Submit][Status] Description 奶牛贝茜被雇去建设N(2≤N≤1000)个牛棚间的互联网.她已经勘探出M(1≤M≤ 20000)条可建的线路,每条线路连接两个牛棚,而且会苞费C(1≤C≤100000).农夫约翰吝啬得很,他希望建设费用最少甚至他都不想给贝茜工钱. 

BZOJ 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 [后缀数组]

1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1017  Solved: 561[Submit][Status][Discuss] Description 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的质量,但连续的若干天的质量有很多重叠.我们称之为一个“模式”. John的牛奶按质量可以被赋予一个0到1000000之间的

BZOJ 1648: [Usaco2006 Dec]Cow Picnic 奶牛野餐( dfs )

直接从每个奶牛所在的farm dfs , 然后算一下.. ---------------------------------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #include<vector> #define rep( i ,

BZOJ 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式( 二分答案 + 后缀数组 )

二分答案m, 后缀数组求出height数组后分组来判断. ------------------------------------------------------------ #include<bits/stdc++.h> using namespace std; const int maxn = 20009; struct HASH { int id[maxn], N; HASH() { N = 0; } inline void work() { sort(id, id + N); N

BZOJ 1649: [Usaco2006 Dec]Cow Roller Coaster( dp )

有点类似背包 , 就是那样子搞... ------------------------------------------------------------------------------------ #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define rep( i , n ) for( int i = 0 ;  i < n ; ++i

bzoj 3390: [Usaco2004 Dec]Bad Cowtractors牛的报复 -- 最大生成树

3390: [Usaco2004 Dec]Bad Cowtractors牛的报复 Time Limit: 1 Sec  Memory Limit: 128 MB Description 奶牛贝茜被雇去建设N(2≤N≤1000)个牛棚间的互联网.她已经勘探出M(1≤M≤ 20000)条可建的线路,每条线路连接两个牛棚,而且会苞费C(1≤C≤100000).农夫约翰吝啬得很,他希望建设费用最少甚至他都不想给贝茜工钱. 贝茜得知工钱要告吹,决定报复.她打算选择建一些线路,把所有牛棚连接在一起,让约翰花

BZOJ 1648: [Usaco2006 Dec]Cow Picnic 奶牛野餐

Description The cows are having a picnic! Each of Farmer John's K (1 <= K <= 100) cows is grazing in one of N (1 <= N <= 1,000) pastures, conveniently numbered 1...N. The pastures are connected by M (1 <= M <= 10,000) one-way paths (no p

BZOJ 1679 [Usaco2005 Jan]Moo Volume 牛的呼声

解法1: N^2的暴力程序,卡卡常数就过了. #include <cstdio> #include <algorithm> #include <cmath> int n; int a[10005]; long long tot; inline bool Read(int &ret){ char c; int flag = 1; if(c=getchar(),c==EOF) return 0; while(c!='-' && (c<'0'||