zoukankan      html  css  js  c++  java
  • bzoj 3238差异

    3238: [Ahoi2013]差异

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 1420  Solved: 662
    [Submit][Status][Discuss]

    Description

    Input

    一行,一个字符串S

    Output

    一行,一个整数,表示所求值

    Sample Input

    cacao

    Sample Output


    54

    HINT



    2<=N<=500000,S由小写英文字母组成

     
    题解:
    right集合:pnt树上的子树sz大小(不统计nq节点)
    把串倒过来建后缀自动机,两个状态的lcp是pnt树上lca的val,也是串中两个前缀的最长公共后缀,即为原串的最长公共前缀。
    一个点的所有儿子的每个出现位置两两的lcp均为这个点的val,剩下的是减去子树内lcp更长的串的贡献。注意减去的应该是sz[i]*sz[i - 1],而不是子树去重后的答案
     
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 #define maxn 1000020
     6 
     7 typedef long long LL;
     8 struct node{
     9     int next[27],val,pnt;
    10 }sam[maxn];
    11 int a[maxn],num[maxn],sz[maxn];
    12 int n,m,root,tot,last;
    13 LL ans,f[maxn],g[maxn];
    14 char ch[maxn];
    15 
    16 inline void add(int x){
    17     int np = ++tot,p = last;
    18     sam[np].val = sam[p].val + 1;
    19     sz[np] = 1;
    20     while ( p && !sam[p].next[x] ) sam[p].next[x] = np , p = sam[p].pnt;
    21     int q = sam[p].next[x];
    22     if ( !q ) sam[p].next[x] = np , sam[np].pnt = p;
    23     else if ( q && sam[p].val + 1 == sam[q].val ) sam[np].pnt = q;
    24     else{
    25         int nq = ++tot;
    26         sam[nq].val = sam[p].val + 1;
    27         sam[nq].pnt = sam[q].pnt;
    28         sam[q].pnt = sam[np].pnt = nq;
    29         memcpy(sam[nq].next,sam[q].next,sizeof(sam[q].next));
    30         while ( p && sam[p].next[x] == q ) sam[p].next[x] = nq , p = sam[p].pnt;
    31         if ( sam[p].next[x] == q ) sam[p].next[x] = nq;
    32     }
    33     last = np;
    34 }
    35 inline void getsort(){
    36     for (int i = 1 ; i <= tot ; i++) num[sam[i].val]++;
    37     for (int i = 1 ; i <= n ; i++) num[i] += num[i - 1];
    38     for (int i = 1 ; i <= tot ; i++) a[num[sam[i].val]--] = i;
    39     for (int i = tot ; i >= 1 ; i--) {
    40         sz[sam[a[i]].pnt] += sz[a[i]];
    41            f[a[i]] += (LL)sz[a[i]] * (sz[a[i]] - 1);
    42         f[sam[a[i]].pnt] -= (LL)sz[a[i]] * (sz[a[i]] - 1);
    43     }
    44 }
    45 int main(){
    46     scanf("%s",ch + 1);
    47     n = strlen(ch + 1);
    48     for (int i = n ; i >= 1 ; i--){
    49         add(ch[i] - 'a');
    50     }
    51     getsort();
    52     ans = (LL)(n + 1) * n * (n - 1) >> 1;
    53     for (int i = 1 ; i <= tot ; i++) ans -= f[i] * (LL)sam[i].val;
    54     printf("%lld
    ",ans);
    55     return 0;
    56 }
    View Code
     
  • 相关阅读:
    Delphi公用函数单元
    Delphi XE5 for Android (十一)
    Delphi XE5 for Android (十)
    Delphi XE5 for Android (九)
    Delphi XE5 for Android (八)
    Delphi XE5 for Android (七)
    Delphi XE5 for Android (五)
    Delphi XE5 for Android (四)
    Delphi XE5 for Android (三)
    Delphi XE5 for Android (二)
  • 原文地址:https://www.cnblogs.com/zqq123/p/5282793.html
Copyright © 2011-2022 走看看