zoukankan      html  css  js  c++  java
  • bzoj 3238

    建出后缀自动机,考虑每条边的贡献。

    发现后缀自动机的val和right集合大小都可以在转移DAG上DP(需要记录每个终止位置所在节点)。

     1 /**************************************************************
     2     Problem: 3238
     3     User: idy002
     4     Language: C++
     5     Result: Accepted
     6     Time:2444 ms
     7     Memory:122388 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 #include <cstring>
    12 #define N 500010
    13 #define S N<<1
    14  
    15 typedef long long dnt;
    16  
    17 int n;
    18 int son[S][26], pnt[S], val[S], rsz[S], ntot, last;
    19 int idgr[S], qu[S], bg, ed;
    20 char buf[N];
    21 dnt ans;
    22  
    23 void init() {
    24     pnt[0] = -1;
    25 }
    26 void append( int c ) {
    27     int p = last;
    28     int np = ++ntot;
    29     val[np] = val[p]+1;
    30     while( p!=-1 && !son[p][c] )
    31         son[p][c]=np, p=pnt[p];
    32     if( p==-1 ) {
    33         pnt[np] = 0;
    34     } else {
    35         int q=son[p][c];
    36         if( val[q]==val[p]+1 ) {
    37             pnt[np] = q;
    38         } else {
    39             int nq = ++ntot;
    40             memcpy( son[nq], son[q], sizeof(son[nq]) );
    41             val[nq] = val[p]+1;
    42             pnt[nq] = pnt[q];
    43             pnt[q] = pnt[np] = nq;
    44             while( p!=-1 && son[p][c]==q )
    45                 son[p][c]=nq, p=pnt[p];
    46         }
    47     }
    48     last = np;
    49     rsz[np] = 1;
    50 }
    51 void make_topo() {
    52     bg=1, ed=0;
    53     for( int u=1; u<=ntot; u++ )
    54         idgr[pnt[u]]++;
    55     for( int u=0; u<=ntot; u++ )
    56         if( idgr[u]==0 && u ) qu[++ed]=u;
    57     while( bg<=ed ) {
    58         int u=qu[bg++];
    59         idgr[pnt[u]]--;
    60         if( idgr[pnt[u]]==0 && pnt[u] )
    61             qu[++ed] = pnt[u];
    62     }
    63 }
    64 int main() {
    65     scanf( "%s", buf );
    66     n = strlen(buf);
    67     init();
    68     for( int i=0; buf[i]; i++ )
    69         append( buf[i]-'a' );
    70     make_topo();
    71     for( int i=1; i<=ed; i++ ) {
    72         int u=qu[i];
    73         rsz[pnt[u]] += rsz[u];
    74     }
    75     dnt ans = 0;
    76     for( int u=1; u<=ntot; u++ ) 
    77         ans += ((dnt)rsz[u]*(rsz[u]-1)*(val[u]-val[pnt[u]]));
    78     ans = -ans;
    79     for( int i=1; i<=n; i++ )
    80         ans += (dnt)i*(n-i)+((dnt)(n-i)*(i+n+1)>>1);
    81     printf( "%lld
    ", ans );
    82 }
    View Code
  • 相关阅读:
    闭包
    作用域
    既然踏足前端,便要立志成为专家
    D3引擎用正则运算的方式,实现智能设备APP消息推送
    基于ArduinoUNOR3的智能调速风扇
    【一起来玩RTOS系列】之RT-Thread Nano快速创建工程
    MCU代码自动生成工具,全面升级
    ESP8266 SOC门磁系统(一)---短信报警功能
    正点原子F407/103,接入机智云,点亮LED
    机智云5.0推出IoT套件GoKit4.0 可实现物联网应用协同开发
  • 原文地址:https://www.cnblogs.com/idy002/p/4518271.html
Copyright © 2011-2022 走看看