zoukankan      html  css  js  c++  java
  • BZOJ1461 字符串的匹配

    什么字符串。。。明明是两个数列。。。

    分类上来讲,还是一道很好的noip题。。。(雾)

    首先,kmp会不会?(答:会!)

    其次,树状数组求顺序对会不会?(再答:会!)

    讲完了!>.<

    进入正题:

    首先,要知道kmp匹配是O(m + n)的原因,是因为匹配每一位的时间是O(1)的。。。

    而我们这里是一个数列,每一位需要搞出一个特征值,使得特征值相同 <=> 可以匹配这一位

    于是就想到了以这一位为末位的当前已匹配区间内的动态顺序对的数目,而求这个东西是O(n * log n)的

    故总复杂度O(m * log m + n * log n)

      1 /**************************************************************
      2     Problem: 1461
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:644 ms
      7     Memory:12564 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <cstring>
     12  
     13 #define lowbit(x) x & -x
     14 using namespace std;
     15 const int S = 10005;
     16 const int N = 500005;
     17 int a[N], b[N], les[N], equ[N], next[N], ans[N];
     18 int BIT[S];
     19 int n, m, s, tot;
     20  
     21 inline int read(){
     22     int x = 0, sgn = 1;
     23     char ch = getchar();
     24     while (ch < '0' || ch > '9'){
     25         if (ch == '-') sgn = -1;
     26         ch = getchar();
     27     }
     28     while (ch >= '0' && ch <= '9'){
     29         x = x * 10 + ch - '0';
     30         ch = getchar();
     31     }
     32     return sgn * x;
     33 }
     34  
     35 inline void add(int x, int del){
     36     while (x <= s)
     37         BIT[x] += del, x += lowbit(x);
     38 }
     39  
     40 inline int query(int x){
     41     int res = 0;
     42     while (x)
     43         res += BIT[x], x -= lowbit(x);
     44     return res;
     45 }
     46  
     47 void get_next(){
     48     memset(BIT, 0, sizeof(BIT));
     49     next[1] = 0;
     50     int i = 2, j = 0, k;
     51     for (; i <= m; ++i){
     52         add(b[i], 1);
     53         while (j && (query(b[i] - 1) != les[j + 1] || query(b[i]) != equ[j + 1])){
     54             for (k = i - j; k < i - next[j]; ++k)
     55                 add(b[k], -1);
     56             j = next[j];
     57         }
     58         next[i] = ++j;
     59     }
     60 }
     61  
     62 void kmp(){
     63     memset(BIT, 0, sizeof(BIT));
     64     int i = 1, j = 0, k, res = 0;
     65     for (; i <= n; ++i){
     66         add(a[i], 1);
     67         while (j && (query(a[i] - 1) != les[j + 1] || query(a[i]) != equ[j + 1])){
     68             for (k = i - j; k < i - next[j]; ++k)
     69                 add(a[k], -1);
     70             j = next[j];
     71         }
     72         if (j == m - 1){
     73             ans[++tot] = i - j;
     74             for (k = i - j; k < i - next[j]; ++k)
     75                 add(a[k], -1);
     76             j = next[j];
     77         }
     78         ++j;
     79     }
     80 }
     81  
     82 int main(){
     83     int i;
     84     n = read(), m = read(), s = read();
     85     for (i = 1; i <= n; ++i)
     86         a[i] = read();
     87     for (i = 1; i <= m; ++i)
     88         b[i] = read();
     89     memset(BIT, 0, sizeof(BIT));
     90     for (i = 1; i <= m; ++i){
     91         add(b[i], 1);
     92         les[i] = query(b[i] - 1);
     93         equ[i] = query(b[i]);
     94     }
     95     get_next();
     96     kmp();
     97     printf("%d
    ", tot);
     98     for (i = 1; i <= tot; ++i)
     99         printf("%d
    ", ans[i]);
    100     return 0;
    101 }
    View Code

    (p.s. 如有不懂请Orz此巨巨)

    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    js精度丢失问题处理
    button居中
    js存储 cookie,localStorage,sessionStorage的比较
    js 常用的DOM,BOM操作
    js事件代理理解
    oneplus前端开发面试
    instanceof
    js原型和原型链
    js构造函数
    NC 6.X笔记(编辑中)
  • 原文地址:https://www.cnblogs.com/rausen/p/4077293.html
Copyright © 2011-2022 走看看