zoukankan      html  css  js  c++  java
  • bzoj2384

    树状数组+KMP

    匹配问题上KMP

    但是问题在于如何判断两个位置相等,我们认为如果一个位置之前比他小的数数量相同那么就是相等。

    那么我们用树状数组动态维护这个东西,每次跳nxt的时候用树状数组删除数。因为每个数只加入一次,所以复杂度是nlogn的,为什么这样是对的呢?我们这么想,对于当前加入最后的一个字符,这个肯定是对的,如果我们再加入一个数,如果比这个数小,那么影响,否则不影响,现在两个串同时加入两个数,那么如果一个相对大一个相对小,那么这个位置肯定是不匹配的,所以即使影响了之前也没关系。大概是这样吧

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N = 1e6 + 5;
    int n, m;
    int a[N], tree[N], s[N], v[N], b[N], c[N], nxt[N], ans[N];
    void update(int x, int d)
    {
        for(; x <= m; x += x & -x) tree[x] += d;
    }
    int query(int x)
    {
        int ret = 0;
        for(; x; x -= x & -x) ret += tree[x];
        return ret;
    }
    int main()
    {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; ++i) scanf("%d", &a[i]), s[a[i]] = i;
        for(int i = 1; i <= n; ++i) v[i] = query(s[i]), update(s[i], 1);
        for(int i = 1; i <= m; ++i) scanf("%d", &b[i]), c[i] = b[i];
        memset(tree, 0, sizeof(tree));
        for(int i = 2, j = 0; i <= n; ++i)
        {
            while(query(s[i]) != v[j + 1]) 
            {
                for(int k = i - j; k < i - nxt[j]; ++k) update(s[k], -1);
                j = nxt[j];
            }
            if(query(s[i]) == v[j + 1])
            {
                update(s[i], 1);
                ++j;
            }
            nxt[i] = j;
        }
        sort(c + 1, c + m + 1);
        memset(tree, 0, sizeof(tree));
        for(int i = 1, j = 0; i <= m; ++i)
        {
            b[i] = lower_bound(c + 1, c + m + 1, b[i]) - c;
            while(j == n || query(b[i]) != v[j + 1])
            {
                for(int k = i - j; k < i - nxt[j]; ++k) update(b[k], -1);
                j = nxt[j];
            }
            if(query(b[i]) == v[j + 1])
            {
                ++j;
                update(b[i], 1);
            }
            if(j == n) ans[++ans[0]] = i - j + 1;
        }
        printf("%d
    ", ans[0]);
        for(int i = 1; i <= ans[0]; ++i) printf("%d%c", ans[i], i == ans[0] ? '
    ' : ' ');
        return 0;
    }
    
    View Code
  • 相关阅读:
    socket.io笔记
    node express+socket.io实现聊天室
    socket.io中 connect与connection的区别
    css clip-path的polygon属性绘制多边形
    vue 3.0
    angular
    项目总结61:IDEA远程调试linux下的tomcat
    Java深入学习28:Redisson分布式锁的使用
    Java深入学习27:Java反射
    Java深入学习28:Runnable和Callable
  • 原文地址:https://www.cnblogs.com/19992147orz/p/7868097.html
Copyright © 2011-2022 走看看