zoukankan      html  css  js  c++  java
  • HDU 5343 MZL's Circle Zhou

    MZL's Circle Zhou

    Time Limit: 1000ms
    Memory Limit: 131072KB
    This problem will be judged on HDU. Original ID: 5343
    64-bit integer IO format: %I64d      Java class name: Main
     

    MZL's Circle Zhou is good at solving some counting problems. One day, he comes up with a counting problem:
    You are given two strings a,b which consist of only lowercase English letters. You can subtract a substring x (maybe empty) from string a and a substring y (also maybe empty) from string b, and then connect them as x+y with x at the front and y at the back. In this way, a series of new strings can be obtained.
    The question is how many different new strings can be obtained in this way.
    Two strings are different, if and only if they have different lengths or there exists an integer i such that the two strings have different characters at position i.

    Input
    The first line of the input is a single integer T (T≤5), indicating the number of testcases.
    For each test case, there are two lines, the first line is string a, and the second line is string b. 1<=|a|,|b|<=90000.

    Output

    For each test case, output one line, a single integer indicating the answer.
     

    Sample Input

    2
    acbcc
    cccabc
    bbbabbababbababbaaaabbbbabbaaaabaabbabbabbbaaabaab
    abbaabbabbaaaabbbaababbabbabababaaaaabbaabbaabbaab

    Sample Output

    135
    557539

    Source

     
    解题:后缀自动机

    A、B两串分别建两个SAM处理,先将B串翻转,利用SAM(B)求以字符c结尾(开头)的子串个数。

    对于SAM(A)中节点x,若x不能接受字符c,则将B串中以c开头的子串“接”在其后,构成Asub+Bsub的形式。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef unsigned long long ULL;
     4 const int maxn = 200100;
     5 struct node{
     6     int son[26],f,len,alpha;
     7     void init(){
     8         memset(son,-1,sizeof son);
     9         f = -1;
    10         len = 0;
    11     }
    12 };
    13 struct SAM{
    14     node e[maxn];
    15     int tot,last;
    16     int newnode(int len = 0,int alpha = 0){
    17         e[tot].init();
    18         e[tot].len = len;
    19         e[tot].alpha = alpha;
    20         return tot++;
    21     }
    22     void init(){
    23         tot = last = 0;
    24         newnode();
    25     }
    26     void add(int c){
    27         int p = last,np = newnode(e[p].len + 1,c);
    28         while(p != -1 && e[p].son[c] == -1){
    29             e[p].son[c] = np;
    30             p = e[p].f;
    31         }
    32         if(p == -1) e[np].f = 0;
    33         else{
    34             int q = e[p].son[c];
    35             if(e[p].len + 1 == e[q].len) e[np].f = q;
    36             else{
    37                 int nq = newnode();
    38                 e[nq] = e[q];
    39                 e[nq].len = e[p].len + 1;
    40                 e[np].f = e[q].f = nq;
    41                 while(p != -1 && e[p].son[c] == q){
    42                     e[p].son[c] = nq;
    43                     p = e[p].f;
    44                 }
    45             }
    46         }
    47         last = np;
    48     }
    49 }sam;
    50 char a[maxn],b[maxn];
    51 ULL dp[26];
    52 int main(){
    53     int kase;
    54     scanf("%d",&kase);
    55     while(kase--){
    56         scanf("%s%s",a,b);
    57         reverse(b,b + strlen(b));
    58         sam.init();
    59         node *e = sam.e;
    60         memset(dp,0,sizeof dp);
    61         for(int i = 0; b[i]; ++i)
    62             sam.add(b[i] - 'a');
    63         for(int i = 1; i < sam.tot; ++i)
    64             dp[e[i].alpha] += e[i].len - e[e[i].f].len;
    65         sam.init();
    66         ULL ret = 0;
    67         for(int i = 0; a[i]; ++i)
    68             sam.add(a[i] - 'a');
    69         for(int i = 1; i < sam.tot; ++i){
    70             ret += e[i].len - e[e[i].f].len;
    71             for(int j = 0; j < 26; ++j)
    72                 if(e[i].son[j] == -1) ret += dp[j]*(e[i].len - e[e[i].f].len);
    73         }
    74         printf("%I64u
    ",ret + 1);
    75     }
    76     return 0;
    77 }
    View Code
  • 相关阅读:
    C# 16进制字节转Int(涉及:Base64转byte数组)
    c# CRC-16 / MODBUS 校验计算方法 及 异或校验算法
    SqlSugar 用法大全
    SQL Server-聚焦NOLOCK、UPDLOCK、HOLDLOCK、READPAST你弄懂多少?
    使用 tabindex 配合 focus-within 巧妙实现父选择器
    DataX 3.0 源码解析一
    Golang必备技巧:接口型函数
    PID控制
    dockerfile,拷贝文件夹到镜像中(不是拷贝文件夹中的内容到镜像)
    什么是PKI?主要作用是什么?
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4820590.html
Copyright © 2011-2022 走看看