0、题意:给定N个原始字符串S,M次查询某个特殊的字符串S’在多少个原始串中出现过。

1、分析:这个题我们第一感觉就是可以用后缀自动机来搞,然后我们发现不是本质不同的字串。。求出现过的次数,也就是说多次出现只算一次。。。然后我们依旧用建立后缀自动机,然后我们观察到询问是可以离线的。。然后冷静一下QAQ……好了。。询问可以离线后,我们对这个树形结构求一下dfs序,然后我们就可以把树上的询问变成一个序列的区间查询,然后就变成了BZOJ1878HH的项链。。具体怎么搞呢?我们可以将询问排序,然后离线的扫一遍,记录一下x的颜色的上一次出现位置,然后转移就好

#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;

inline int read(){
    char ch = getchar(); int x = 0, f = 1;
    while(ch < '0' || ch > '9'){
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while('0' <= ch && ch <= '9'){
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

struct Edge{
    int u, v, next;
} G[400010];
int head[200010], tot;
char str[500010];
int first[200010], val[200010], nxt[200010], num;
int C[200010];
int n, m;
int pre[200010];

inline void ues(int u, int v){
    num ++;
    val[num] = v;
    nxt[num] = first[u];
    first[u] = num;
}

inline void add(int x, int y){
    G[++ tot] = (Edge){x, y, head[x]};
    head[x] = tot;
}

map<int , int> :: iterator it;

int vis[200010];
int last, cnt, p, np, q, nq;
int len[200010], fa[200010];
map<int , int> tranc[200010];
int right[200010], c[200010], od[200010];
int tim;
int ans[200010];

inline void insert(int c, int w){
    p = last;
    if(tranc[p][c] != 0){
        q = tranc[p][c];
        if(len[q] == len[p] + 1) last = tranc[p][c];
        else{
            nq = ++ cnt; len[nq] = len[p] + 1;
            for(it = tranc[q].begin(); it != tranc[q].end(); it ++){
                tranc[nq][it -> first] = it -> second;
            }
            fa[nq] = fa[q];
            fa[q] = nq;
            while(tranc[p][c] == q){
                tranc[p][c] = nq;
                p = fa[p];
            }
            last = nq;
        }
    }
    else{
        last = np = ++ cnt;
        vis[np] = 1;
        len[np] = len[p] + 1;
        tranc[cnt].clear();
        right[np] = 1;
        while(!tranc[p][c] && p) tranc[p][c] = np, p = fa[p];
        if(!p) fa[np] = 1;
        else{
            q = tranc[p][c];
            if(len[q] == len[p] + 1) fa[np] = q;
            else{
                nq = ++ cnt; len[nq] = len[p] + 1;
                for(it = tranc[q].begin(); it != tranc[q].end(); it ++){
                    tranc[nq][it -> first] = it -> second;
                }
                fa[nq] = fa[q];
                fa[q] = fa[np] = nq;
                while(tranc[p][c] == q){
                    tranc[p][c] = nq;
                    p = fa[p];
                }
            }
        }
        last = np;
    }
    ues(last, w);
}

inline void init(){
    memset(head, -1, sizeof(head));
    for(int i = 1; i <= cnt; i ++){
        add(fa[i], i);
    }
}

inline void update(int x, int d){
    if(x == 0) return;
    for(; x <= cnt; x += (x & -x)){
        C[x] += d;
    }
}

inline int sum(int x){
    int ret = 0;
    for(; x > 0; x -= (x & -x)){
        ret += C[x];
    }
    return ret;
}

inline void dfs(int x){
    int t = ++ tim;
    for(int i = first[x]; i; i = nxt[i]){
        update(pre[val[i]], -1);
        update(t, 1);
        pre[val[i]] = t;
    }
    for(int i = head[x]; i != -1; i = G[i].next){
        dfs(G[i].v);
    }
    ans[x] = sum(tim) - sum(t - 1);
}

int query(char *s)
{
    int st = 1;
    while(*s != '\0')
        st = tranc[st][*s], s ++;
    return st;
}  

int main(){
    last = cnt = 1;
    n = read(); m = read();
    for(int i = 1; i <= n; i ++){
        last = 1;
        scanf("%s", str + 1);
        int L = strlen(str + 1);
        for(int j = 1; j <= L; j ++){
            insert(str[j], i);
        }
    }
    init();
    dfs(1);
    for(int i = 1; i <= m; i ++){
        scanf("%s", str);
        printf("%d\n", ans[query(str)]);
    }
    return 0;
}

BZOJ2780——[Spoj]8093 Sevenk Love Oimaster的更多相关文章

  1. BZOJ2780 [Spoj]8093 Sevenk Love Oimaster 【广义后缀自动机】

    题目 Oimaster and sevenk love each other. But recently,sevenk heard that a girl named ChuYuXun was dat ...

  2. BZOJ2780: [Spoj]8093 Sevenk Love Oimaster(广义后缀自动机,Parent树,Dfs序)

    Description Oimaster and sevenk love each other. But recently,sevenk heard that a girl named ChuYuXu ...

  3. Bzoj2780: [Spoj]8093 Sevenk Love Oimaster

    题目 传送门 Sol 就是广义\(sam\) 然后记录下每个状态属于哪些串,开\(set\)维护 \(parent\)树上启发式合并一下就好了 # include <bits/stdc++.h& ...

  4. 【BZOJ2780】[Spoj]8093 Sevenk Love Oimaster 广义后缀自动机

    [BZOJ2780][Spoj]8093 Sevenk Love Oimaster Description Oimaster and sevenk love each other.     But r ...

  5. 三种做法:BZOJ 2780: [Spoj]8093 Sevenk Love Oimaster

    目录 题意 思路 AC_Code1 AC_Code2 AC_Code3 参考 @(bzoj 2780: [Spoj]8093 Sevenk Love Oimaster) 题意 链接:here 有\(n ...

  6. BZOJ 2780: [Spoj]8093 Sevenk Love Oimaster( 后缀数组 + 二分 + RMQ + 树状数组 )

    全部串起来做SA, 在按字典序排序的后缀中, 包含每个询问串必定是1段连续的区间, 对每个询问串s二分+RMQ求出包含s的区间. 然后就是求区间的不同的数的个数(经典问题), sort queries ...

  7. BZOJ 2780: [Spoj]8093 Sevenk Love Oimaster [广义后缀自动机]

    JZPGYZ - Sevenk Love Oimaster     Oimaster and sevenk love each other.       But recently,sevenk hea ...

  8. bzoj 2780 [Spoj]8093 Sevenk Love Oimaster

    LINK:Sevenk Love Oimaster 询问一个模式串在多少个文本串中出现过. 考虑广义SAM 统计这种数量问题一般有三种做法. 一种 暴力bitset 这道题可能可以过? 一种 暴力跳p ...

  9. 【刷题】BZOJ 2780 [Spoj]8093 Sevenk Love Oimaster

    Description Oimaster and sevenk love each other. But recently,sevenk heard that a girl named ChuYuXu ...

随机推荐

  1. linux系统命令

    TOP命令 top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器.top是一个动态显示过程, 即可以通过用户按键来不断刷新当前状态.如 ...

  2. c#优化

    优化反射 http://kb.cnblogs.com/page/172119/ http://www.2cto.com/kf/201301/182765.html http://blog.sina.c ...

  3. mysql 字符串

    mysql中一个字符串,既可以用两个单引号表示,也可以用两个双引号表示. 比如字符串 wangxiaowei,用单引号表示 'wangxiaowei',双引号表示"wangxiaowei&q ...

  4. 11 Clever Methods of Overfitting and how to avoid them

    11 Clever Methods of Overfitting and how to avoid them Overfitting is the bane of Data Science in th ...

  5. nginx和fpm的进程数配置和502,504错误

    502 和 php-fpm.conf 1.php-cgi进程数不够用.php执行时间长,导致没有空闲进程处理新请求. 2.php-cgi进程死掉.php-fpm超时时间短,当前进程执行超时关闭连接. ...

  6. 浅谈JavaScript中的能力检测

    引言 我们知道,各个版本的浏览器有着许多不一致性.理想状态下,应该是所有的浏览器都提供一套标准的API接口.但是现实中,各个版本的浏览器存在的怪癖非常多,我们通常都是使用客户端检测来作为补救措施.但是 ...

  7. Java并发编程核心方法与框架-CountDownLatch的使用

    Java多线程编程中经常会碰到这样一种场景:某个线程需要等待一个或多个线程操作结束(或达到某种状态)才开始执行.比如裁判员需要等待运动员准备好后才发送开始指令,运动员要等裁判员发送开始指令后才开始比赛 ...

  8. 是时候放弃Uploadify了

    1.Uploadify是什么? Uploadify是来自国外的一款优秀jQuery插件,主要功能是批量上传文件. 这话是复制百度百科的,是:基于jQuery开发的文件上传插件. 2.为什么大家都在用? ...

  9. Jedis 例子(demo)大全

    第一步:到git下载jedis源码,如果你用maven或者gradle,那么直接下官方的即可,地址:https://github.com/xetorthio/jedis:如果你用ant,下载这个:ht ...

  10. array_fill 用给定的值填充数组

    转自:http://www.phpstudy.net/php/165.html PHP array_fill 用给定的值填充数组 array_fill (PHP 4 >= 4.2.0, PHP ...