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
     
  • 相关阅读:
    Mongodb_文件存储
    Mongodb_技巧
    Blend_Effect
    WPF_界面_图片/界面/文字模糊解决之道整理
    ASP.NET Boilerplate 深入系列之:概述
    P1280 尼克的任务
    P1802 5倍经验日
    271. 杨老师的照相排列
    P1726 上白泽慧音
    P1983 [NOIP2013 普及组] 车站分级
  • 原文地址:https://www.cnblogs.com/zqq123/p/5282793.html
Copyright © 2011-2022 走看看