zoukankan      html  css  js  c++  java
  • AC自动机(二次加强版)

    题目链接 P5357

      要找每个串的出现次数,实际上就是在fail树上进行处理了,我们知道,在fail树的祖先节点上的点,一定是在这之前的前缀的点,所以直接进行跳转就可以了。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cmath>
      4 #include <string>
      5 #include <cstring>
      6 #include <algorithm>
      7 #include <limits>
      8 #include <vector>
      9 #include <stack>
     10 #include <queue>
     11 #include <set>
     12 #include <map>
     13 #include <bitset>
     14 #include <unordered_map>
     15 #include <unordered_set>
     16 #define lowbit(x) ( x&(-x) )
     17 #define pi 3.141592653589793
     18 #define e 2.718281828459045
     19 #define INF 0x3f3f3f3f
     20 #define HalF (l + r)>>1
     21 #define lsn rt<<1
     22 #define rsn rt<<1|1
     23 #define Lson lsn, l, mid
     24 #define Rson rsn, mid+1, r
     25 #define QL Lson, ql, qr
     26 #define QR Rson, ql, qr
     27 #define myself rt, l, r
     28 #define pii pair<int, int>
     29 #define MP(a, b) make_pair(a, b)
     30 using namespace std;
     31 typedef unsigned long long ull;
     32 typedef unsigned int uit;
     33 typedef long long ll;
     34 const int maxN = 2e5 + 7;
     35 int N, tot, root;
     36 struct Trie_node
     37 {
     38     int nex[26], fail; vector<int> val;
     39     Trie_node() { memset(nex, 0, sizeof(nex)); val.clear(); fail = 0; }
     40     void clear() { memset(nex, 0, sizeof(nex)); val.clear(); fail = 0; }
     41 } t[maxN];
     42 char s[maxN], T[2000006];
     43 void Insert(int ith)
     44 {
     45     int len = (int)strlen(s), u = root;
     46     for(int i=0, id; i<len; i++)
     47     {
     48         id = s[i] - 'a';
     49         if(!t[u].nex[id])
     50         {
     51             t[u].nex[id] = ++tot;
     52             t[tot].clear();
     53         }
     54         u = t[u].nex[id];
     55     }
     56     t[u].val.push_back(ith);
     57 }
     58 int que[maxN], top, tail;
     59 void build_fail()
     60 {
     61     top = tail = 0;
     62     que[tail++] = root;
     63     int tmp, p, son;
     64     while(top < tail)
     65     {
     66         tmp = que[top++];
     67         for(int i=0; i<26; i++)
     68         {
     69             son = t[tmp].nex[i];
     70             if(son)
     71             {
     72                 if(!tmp) t[son].fail = 0;
     73                 else
     74                 {
     75                     p = t[tmp].fail;
     76                     while(p && !t[p].nex[i]) p = t[p].fail;
     77                     t[son].fail = t[p].nex[i];
     78                 }
     79                 que[tail++] = son;
     80             }
     81             else t[tmp].nex[i] = t[t[tmp].fail].nex[i];
     82         }
     83     }
     84 }
     85 vector<int> to[maxN];
     86 int siz[maxN] = {0}, maxx;
     87 int ans[maxN];
     88 void dfs(int u)
     89 {
     90     for(int v : to[u])
     91     {
     92         dfs(v);
     93         siz[u] += siz[v];
     94     }
     95     if(!t[u].val.empty())
     96     {
     97         for(int i : t[u].val)
     98         {
     99             ans[i] = siz[u];
    100         }
    101     }
    102 }
    103 int main()
    104 {
    105     scanf("%d", &N);
    106     tot = 0; root = 0;
    107     t[root].clear();
    108     for(int i=1; i<=N; i++)
    109     {
    110         scanf("%s", s);
    111         Insert(i);
    112     }
    113     build_fail();
    114     for(int i=0; i<=tot; i++) { to[i].clear(); siz[i] = 0; }
    115     for(int i=1; i<=tot; i++) to[t[i].fail].push_back(i);
    116     scanf("%s", T);
    117     int u = root, len = (int)strlen(T);
    118     for(int i=0, id; i<len; i++)
    119     {
    120         id = T[i] - 'a';
    121         while(u && !t[u].nex[id]) u = t[u].fail;
    122         u = t[u].nex[id];
    123         siz[u]++;
    124     }
    125     maxx = 0;
    126     dfs(root);
    127     for(int i=1; i<=N; i++) printf("%d
    ", ans[i]);
    128     return 0;
    129 }
  • 相关阅读:
    反转链表 16
    CodeForces 701A Cards
    hdu 1087 Super Jumping! Jumping! Jumping!(动态规划)
    hdu 1241 Oil Deposits(水一发,自我的DFS)
    CodeForces 703B(容斥定理)
    poj 1067 取石子游戏(威佐夫博奕(Wythoff Game))
    ACM 马拦过河卒(动态规划)
    hdu 1005 Number Sequence
    51nod 1170 1770 数数字(数学技巧)
    hdu 2160 母猪的故事(睡前随机水一发)(斐波那契数列)
  • 原文地址:https://www.cnblogs.com/WuliWuliiii/p/13714305.html
Copyright © 2011-2022 走看看