• 1009 失恋的小 T(后缀数组¥)


    1009: 失恋的小 T

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 160  解决: 76
    [提交][状态][讨论版]

    题目描述

    小 T 最近失恋了,开始怀疑人生和爱情,他想知道在这世界中去伪存真后还剩多少。 
    小 T 在网上拿到了代表大千世界的长字符串,删掉了所有换行空格和标点符号,只剩下了小写字母。 
    现在字符串中有好多重复的子串,相同子串里只有一个是 Real 的。 
    为了让小 T 走出失恋,你一定要告诉他这个世界上 Real 的东西有多少。 
    (子串:串中任意个连续的字符组成的子序列称为该串的子串) 

    输入

    包含 100 组输入,每组为一行字符串,只包含小写字母,长度 1-5000。 

    输出

    输出 100 行,每行一个整数,对应输入的答案。 

    样例输入

    aaba
    

    样例输出

    8
    

    提示

    后缀数组,

    我还不会,,

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<math.h>
     4 #include <string>
     5 #include<string.h>
     6 #include<map>
     7 #include<queue>
     8 #include<set>
     9 #include<utility>
    10 #include<vector>
    11 #include<algorithm>
    12 #include<stdlib.h>
    13 using namespace std;
    14 #define maxn 200100
    15 #define maxm 200005
    16 #define rd(x) scanf("%d", &x)
    17 #define rd2(x, y) scanf("%d%d", &x, &y)
    18 #define mod 1000000007
    19 const int MAXN = 20010;
    20 int t1[MAXN],t2[MAXN],c[MAXN];
    21 bool cmp(int *r, int a,int b,int l){
    22     return r[a] ==r[b] && r[a+l] == r[b+l];
    23 }
    24 void da(int str[], int sa[], int rankk[], int height[], int n, int m){
    25     n++;
    26     int i,j,p,*x =t1,*y=t2;
    27     for(i =0; i <m; i++) c[i] =0;
    28     for(i = 0; i <n; i++) c[x[i] =str[i]]++;
    29     for(i =1; i < m; i++) c[i] += c[i-1];
    30     for(i = n-1;i >= 0; i--) sa[--c[x[i]]] = i;
    31     for(j =1; j <= n; j <<=1){
    32         p =0;
    33         for(i = n-j; i <n; i++) y[p++] = i;
    34         for(i = 0; i < n; i++) if(sa[i] >= j) y[p++] = sa[i] -j;
    35 
    36         for(i = 0; i < m; i++) c[i] =0;
    37         for(i = 0 ;i < n; i++) c[x[y[i]]]++;
    38         for(i = 1; i < m; i++) c[i] += c[i-1];
    39         for(i = n-1; i >=0; i--) sa[--c[x[y[i]]]] = y[i];
    40         swap(x,y);
    41         p =1; x[sa[0]] =0;
    42         for(int i = 1; i < n; i++) x[sa[i]] = cmp(y, sa[i-1], sa[i], j)?p-1:p++;
    43         if(p >= n) break;
    44         m =p;
    45     }
    46     int k =0;
    47     n--;
    48     for(i = 0; i <= n;i++) rankk[sa[i]] = i;
    49     for(i = 0; i < n;i++){
    50         if(k) k--;
    51         j =sa[rankk[i]-1];
    52         while(str[i+k] == str[j+k]) k++;
    53         height[rankk[i]] = k;
    54     }
    55 }
    56 int rankk[MAXN],height[MAXN];
    57 char str[MAXN];
    58 int r[MAXN],sa[MAXN];
    59 int main()
    60 {
    61     int t = 100;
    62     while(~scanf("%s", str)){
    63         //scanf("%s", str);
    64         int len = strlen(str);
    65         //int n = 2*len +1;
    66         for(int i =0; i < len ;i++) r[i] = str[i];
    67         //for(int i =0; i < len; i++) r[len + 1 + i] = str[len -1 -i];
    68         r[len] =0;
    69         r[len+1] = 0;
    70         da(r, sa, rankk, height,  len , 'z' + 1);
    71         long long int res = len - sa[1];
    72         for(int i= 2 ;i <= len; i++){
    73             res = res + len - sa[i] -height[i];
    74         }
    75         printf("%lld
    ", res);
    76     }
    77     return 0;
    78 }
  • 相关阅读:
    OpenRisc-52-run openrisc&orpmon on ml501 board
    PHP之APC缓存详细介绍(转)
    ios 使用GCD 多线程 教程
    poj2454
    尝鲜delphi开发android/ios_环境搭建
    HDU 3308 线段树 最长连续上升子序列 单点更新 区间查询
    jQuery 表格排序插件 Tablesorter 使用
    Oracle 常见错误
    安卓开发44:解决 INSTALL_FAILED_UID_CHANGED 等问题
    Java的native方法
  • 原文地址:https://www.cnblogs.com/gongpixin/p/6790572.html
Copyright © 2020-2023  润新知