• 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
  • 相关阅读:
    刷过算法题汇总
    List
    PHP+JQUEY+AJAX实现分页
    关于响应式布局
    bootscript/javascript组件
    关于H5框架之Bootstrap的小知识
    SEO优化---学会建立高转化率的网站关键词库
    jQuery Mobile学习笔记
    ANGULAR $HTTP请求
    css3 transition
  • 原文地址:https://www.cnblogs.com/rausen/p/4077293.html
Copyright © 2020-2023  润新知