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
  • 相关阅读:
    windows下使用curl命令,以及常用curl命令
    使用 C# 下载文件的十八般武艺
    初闻不知曲中意,再听已是曲中人
    从线性回归走进机器学习
    自定义Vue&Element组件,实现用户选择和显示
    ARP协议原理——地址解析协议, 用于实现从 IP 地址到 MAC 地址的映射,即询问目标IP对应的MAC地址,ARP整个完整交互过程仅需要两个包,一问一答即可搞定
    SSH加密隧道流量攻击与检测技术——这玩意和思科加密流量检测没有本质区别啊,可借鉴CNN图像
    bt2——基于telegram的C2
    通过gmail进行C2控制——看了下源码,本质上和dropbox c2架构一样,都是去轮训邮件,将c2攻击的东西以邮件形式发送,结果也发到邮箱里
    DropboxC2 工具原理总结——就是通过dropbox文件来间接做c2控制和交互。
  • 原文地址:https://www.cnblogs.com/Mr-ren/p/4223177.html
Copyright © 2011-2022 走看看