• bzoj 3238[Ahoi2013]差异


    3238: [Ahoi2013]差异

    Time Limit: 20 Sec  Memory Limit: 512 MB

    Description

    Input

    一行,一个字符串S

    Output

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

    Sample Input

    cacao

    Sample Output

    54

    HINT

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

    因为要求LCP,还有后缀,所以要用到后缀数组。

    求出height, 对于排名为 i 的后缀, 他和前面每一个后缀的贡献是 len[i] + len[k] - lcp(i, k)

    len[k] 可以用前缀和算, 和前面所有后缀的lcp的和可以用单调栈维护,思路和[Haoi2016]找相同字符 是一样的

    于是就解决了。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #define LL long long
      6 
      7 using namespace std;
      8 
      9 const int MAXN = 6e5 + 10;
     10 
     11 LL m, len;
     12 LL ans = 0;
     13 char s[MAXN];
     14 
     15 LL h[MAXN];
     16 LL c[MAXN], cur[MAXN], ra[MAXN], tp[MAXN], SA[MAXN];
     17 
     18 struct ss {
     19     int id;
     20     LL sum;
     21 } sta[MAXN];
     22 
     23 inline LL read()
     24 {
     25     LL x = 0, w = 1; char ch = 0;
     26     while(ch < '0' || ch > '9') {
     27         if(ch == '-') {
     28             w = -1;
     29         }
     30         ch = getchar();
     31     }
     32     while(ch >= '0' && ch <= '9') {
     33         x = x * 10 + ch - '0';
     34         ch = getchar();
     35     }
     36     return x * w;
     37 }
     38 
     39 void solve(int x)
     40 {
     41     for(int i = 1; i <= x; i++) {
     42         c[i] = 0;
     43     }
     44     for(int i = 1; i <= len; i++) {
     45         c[ra[tp[i]]]++;
     46     }
     47     for(int i = 1; i <= x; i++) {
     48         c[i] += c[i - 1];
     49     }
     50     for(int i = len; i >= 1; i--) {
     51         SA[c[ra[tp[i]]]--] = tp[i];
     52     }
     53 }
     54 
     55 void copy()
     56 {
     57     for(int i = 1; i <= len; i++) {
     58         cur[i] = ra[i];
     59     }
     60 }
     61 
     62 void suffix()
     63 {
     64     for(int i = 1; i <= len; i++) {
     65         ra[i] = s[i];
     66         tp[i] = i;
     67     }
     68     solve(m = 128);
     69     for(int w = 1, p = 0; p < len; w += w, m = p) {
     70         p = 0;
     71         for(int j = len - w + 1; j <= len; j++) {
     72             tp[++p] = j;
     73         }
     74         for(int i = 1; i <= len; i++) {
     75             if(SA[i] > w) {
     76                 tp[++p] = SA[i] - w;
     77             }
     78         }
     79         solve(m);
     80         copy();
     81         ra[SA[1]] = p = 1; 
     82         for(int i = 2; i <= len; i++) {
     83             if(cur[SA[i]] == cur[SA[i - 1]] && cur[SA[i] + w] == cur[SA[i - 1] + w]) {
     84                 ra[SA[i]] = p;
     85             } else {
     86                 ra[SA[i]] = ++p;
     87             }
     88         }
     89     }
     90     int k = 0;
     91     for(int i = 1; i <= len; i++) {
     92         if(k) {
     93             k--;
     94         }
     95         int j = SA[ra[i] - 1];
     96         while(s[i + k] == s[j + k]) {
     97             k++;
     98         }
     99         h[ra[i]] = k;
    100     }
    101 }
    102 
    103 void cal()
    104 {
    105     int top = 1;
    106     LL sum = 0;
    107     for(int i = 1; i <= len; i++) {
    108         while(top > 1 && h[i] < h[sta[top - 1].id]) {
    109             top--;
    110         }
    111         sta[top].id = i;
    112         sta[top].sum = sta[top - 1].sum + (i - sta[top - 1].id) * h[i];
    113         top++;
    114         ans += (i - 1) * (len - SA[i] + 1) + sum - 2 * sta[top - 1].sum;
    115         sum += len - SA[i] + 1;
    116     }
    117     printf("%lld
    ", ans);
    118 }
    119 
    120 int main()
    121 {
    122     scanf("%s", s + 1);
    123     len = strlen(s + 1);
    124     suffix();
    125     cal();
    126 }
    View Code
  • 相关阅读:
    JBuilder链接sql server数据库
    各种数据库连接代码(java)
    各种数据库连接代码的测试类(java)
    简单数据查询语句
    Oracle卸载
    Java字符串转换
    静态类示例
    授权对象的检查
    BAPI
    clear、REFRESH、free区别
  • 原文地址:https://www.cnblogs.com/wuenze/p/8659753.html
Copyright © 2020-2023  润新知