zoukankan      html  css  js  c++  java
  • poj 3167

    Cow Patterns

    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 3414   Accepted: 1263

    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 10
    5
    6
    2
    10
    10
    7
    3
    2
    9
    1
    4
    4
    3
    2
    1

    Sample Output

    1
    3

    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.

    大意:

    给出两个串 A,B 长度分别为 N,K, 两个串均由数字构成且大小不超过 S.

    两个串能够匹配的定义是: 当且仅当匹配两个串的每个数字在匹配区间[L,R]内的排名相等,那么这两个串匹配.

    求 B 在 A 中出现了多少次,并输出每次的匹配位置.

    思路:

    看上去像是 KMP 的问题吧. 但是匹配的定义有变化.....

    我们现在就是要动态维护这个数字在这个匹配区间内的排名,就能够解决这个问题....

    那么怎么维护呢? 题目中的 S 比较小, 所以暴力是没有问题的, 一个优化一点的方式是使用 BIT.

    现在我们就要想办法确定这个区间的值了. 一个比较显然的结论(这为什么是充要条件我没想懂...)就是比x数字小,且和x数字相等的数相同就能够匹配.

    一个预处理的过程就看程序吧.

    然后在计算 kmp 的时候我们通过计算排名来确定匹配,然后通过 插入来维护排名....

    一个需要注意的地方就是: 当 沿着 fail 指针回溯的时候, 我们要撤销操作..... 具体情况, 就看程序吧.

    缩行党 && goto...... 自行无视

     1 #include<cstdlib>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<vector>
     6 using namespace std;
     7 const int maxn = (int)1.5e5;
     8 int n,k,s;
     9 int fail[maxn],str[maxn],pt[maxn];
    10 pair<int,int>rk[maxn];
    11 vector<int>v;
    12 struct BIT{
    13     int bit[50];
    14     void clear(){memset(bit,0,sizeof(bit));}
    15     inline int lowbit(int x){ return x & (-x); }
    16     int less(int pos){ int ret = 0; for(;pos > 0; pos -= lowbit(pos)) ret += bit[pos]; return ret; }
    17     void ins(int pos,int val){for(;pos <= 30; pos += lowbit(pos)) bit[pos] += val;}
    18 }bit;
    19 pair<int,int>rank(int x){
    20     return make_pair(bit.less(x-1), bit.less(x));
    21 }
    22 void getfail(){
    23     bit.clear();
    24     fail[0] = -1;
    25     for(int i = 1, j = 0; i < k;)
    26         if(j == -1 || rank(pt[i]) == rk[j])
    27             bit.ins(pt[i],1), i++, j++, fail[i] = j;
    28         else{
    29             for(int l = i - j; l < i - fail[j]; l++) bit.ins(pt[l],-1);
    30             j = fail[j];
    31         }       
    32 }
    33 void kmp(){
    34     getfail();
    35     bit.clear();
    36     for(int i = 0,j = 0; i < n;){
    37         if(j == -1 || rank(str[i]) == rk[j])
    38             bit.ins(str[i],1), i++, j++;
    39         else{
    40         GT:     for(int l = i - j; l < i - fail[j]; l++) bit.ins(str[l],-1);
    41             j = fail[j]; continue;
    42         }
    43         if(j == k) { v.push_back(i-j+1); goto GT;}
    44     }        
    45 }
    46 int main()
    47 {
    48     freopen("mkp.in","r",stdin);
    49     freopen("mkp.out","w",stdout);
    50     scanf("%d %d %d
    ",&n,&k,&s);
    51     for(int i = 0; i < n; ++i) scanf("%d",&str[i]);
    52     for(int i = 0; i < k; ++i) scanf("%d",&pt[i]);
    53     for(int i = 0; i < k; ++i) rk[i] = rank(pt[i]), bit.ins(pt[i],1);
    54     kmp();
    55     printf("%d
    ",v.size());
    56     for(int i = 0; i < (int)v.size(); ++i) printf("%d
    ",v[i]);
    57     return 0;
    58 }
    View Code
  • 相关阅读:
    圆环自带动画进度条ColorfulRingProgressView
    FragmentTabHost+FrameLayout实现底部菜单栏
    PopupWindowFromBottom 从底部弹出popupwindow
    Android滚动选择控件
    github入门基础之上传本地文件以及安装github客户端
    Android 快速开发系列 ORMLite 框架最佳实践之实现历史记录搜索
    Android 快速开发系列 ORMLite 框架最佳实践
    《Entity Framework 6 Recipes》中文翻译——第十章EntityFramework存储过程处理(一)
    《Entity Framework 6 Recipes》中文翻译——第九章EntityFramework在N层架构程序中的应用(七)
    《Entity Framework 6 Recipes》中文翻译——第九章EntityFramework在N层架构程序中的应用(六)
  • 原文地址:https://www.cnblogs.com/Mr-ren/p/4223177.html
Copyright © 2011-2022 走看看