zoukankan      html  css  js  c++  java
  • bzoj4566 找相同字符

    题意:给定两个字符串,从中各取一个子串使之相同,有多少种取法。允许本质相同。

    解:建立广义后缀自动机,对于每个串,分别统计cnt,之后每个点的cnt乘起来。记得开long long

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cstring>
      4 
      5 typedef long long LL;
      6 const int N = 800010;
      7 
      8 struct Edge {
      9     int nex, v;
     10 }edge[N << 1]; int top;
     11 
     12 int tr[N][26], len[N], fail[N], cnt[N][2], vis[N];
     13 int tot = 1, last, turn, e[N];
     14 char s[N], str[N];
     15 
     16 inline void add(int x, int y) {
     17     top++;
     18     edge[top].v = y;
     19     edge[top].nex = e[x];
     20     e[x] = top;
     21     return;
     22 }
     23 
     24 inline int split(int p, int f) {
     25     int Q = tr[p][f], nQ = ++tot;
     26     len[nQ] = len[p] + 1;
     27     fail[nQ] = fail[Q];
     28     fail[Q] = nQ;
     29     memcpy(tr[nQ], tr[Q], sizeof(tr[Q]));
     30     while(tr[p][f] == Q) {
     31         tr[p][f] = nQ;
     32         p = fail[p];
     33     }
     34     return nQ;
     35 }
     36 
     37 inline int insert(int p, char c) {
     38     int f = c - 'a';
     39     if(tr[p][f]) {
     40         int Q = tr[p][f];
     41         if(len[Q] == len[p] + 1) {
     42             cnt[Q][turn] = 1;
     43             return Q;
     44         }
     45         int t = split(p, f);
     46         cnt[t][turn] = 1;
     47         return t;
     48     }
     49     int np = ++tot;
     50     len[np] = len[p] + 1;
     51     cnt[np][turn] = 1;
     52     while(p && !tr[p][f]) {
     53         tr[p][f] = np;
     54         p = fail[p];
     55     }
     56     if(!p) {
     57         fail[np] = 1;
     58     }
     59     else {
     60         int Q = tr[p][f];
     61         if(len[Q] == len[p] + 1) {
     62             fail[np] = Q;
     63         }
     64         else {
     65             fail[np] = split(p, f);
     66         }
     67     }
     68     return np;
     69 }
     70 
     71 void DFS(int x) {
     72     for(int i = e[x]; i; i = edge[i].nex) {
     73         int y = edge[i].v;
     74         DFS(y);
     75         cnt[x][0] += cnt[y][0];
     76         cnt[x][1] += cnt[y][1];
     77     }
     78     return;
     79 }
     80 
     81 int main() {
     82     scanf("%s%s", s, str);
     83     int n = strlen(s), last = 1;
     84     for(int i = 0; i < n; i++) {
     85         last = insert(last, s[i]);
     86     }
     87     n = strlen(str);
     88     last = turn = 1;
     89     for(int i = 0; i < n; i++) {
     90         last = insert(last, str[i]);
     91     }
     92     for(int i = 2; i <= tot; i++) {
     93         add(fail[i], i);
     94     }
     95     DFS(1);
     96     int p = 1;
     97     LL ans = 0;
     98     for(int i = 2; i <= tot; i++) {
     99         ans += 1ll * cnt[i][0] * cnt[i][1] * (len[i] - len[fail[i]]);
    100     }
    101 
    102     printf("%lld", ans);
    103     return 0;
    104 }
    AC代码
  • 相关阅读:
    《Apache Doris在美团外卖数仓中的应用实践》
    《一文教会你如何写复杂业务的代码》
    《SOFA企业应用框架》
    《为什么阿里巴巴代码规约要求避免使用 Apache BeanUtils 进行属性的拷贝》
    《浅析VO、DTO、DO、PO的概念、区别和用处》
    Spring 注解
    《浅析VO、DTO、DO、PO的概念、区别和用处》
    dsgn_ebook
    《清华大学刘世霞“可解释机器学习的可视化分析”(附PPT)》
    《图结构的相似度度量与分类》
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10234620.html
Copyright © 2011-2022 走看看