• BZOJ3238 [Ahoi2013]差异


    首先把后缀数组和height数组都搞出来。。。

    然后用两个单调栈维护$[l, r]$表示对于一个点$x$,满足$height[x] le height[l..x] &&  height[x] < height[x..r]$的最小的$l$和最大的$r$

    这样子就可以保证不会重复计算了

     1 /**************************************************************
     2     Problem: 3238
     3     User: rausen
     4     Language: C++
     5     Result: Accepted
     6     Time:4496 ms
     7     Memory:20336 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 #include <cstring>
    12  
    13 using namespace std;
    14 typedef long long ll;
    15 const int N = 5e5 + 5;
    16  
    17 int a[N], len;
    18 int sa[N], rank[N], height[N];
    19  
    20 inline void Sort(int *a, int *b, int *c, int n, int m) {
    21     static int i, sum[N];
    22     for (i = 0; i <= m; ++i) sum[i] = 0;
    23     for (i = 0; i < n; ++i) ++sum[c[a[i]]];
    24     for (i = 1; i <= m; ++i) sum[i] += sum[i - 1];
    25     for (i = n - 1; ~i; --i)
    26         b[--sum[c[a[i]]]] = a[i];
    27 }
    28  
    29 void make_sa(int *s) {
    30     int i, j;
    31     static int x[N], y[N];
    32     for (i = 0; i < len; ++i) x[i] = s[i], rank[i] = i;
    33     Sort(rank, sa, x, len, 30);
    34     rank[sa[0]] = 1;
    35     for (i = 1; i < len; ++i)
    36         rank[sa[i]] = rank[sa[i - 1]] + (x[sa[i]] != x[sa[i - 1]]);
    37     for (i = 1; i <= len; i <<= 1) {
    38         for (j = 0; j < len; ++j)
    39             x[j] = rank[j], y[j] = j + i < len ? rank[j + i] : 0, sa[j] = j;
    40         Sort(sa, rank, y, len, len), Sort(rank, sa, x, len, len);
    41         rank[sa[0]] = 1;
    42         for (j = 1; j < len; ++j)
    43             rank[sa[j]] = rank[sa[j - 1]] + (x[sa[j]] != x[sa[j - 1]] || y[sa[j]] != y[sa[j - 1]]);
    44         if (rank[sa[len - 1]] == len) return;
    45     }
    46 }
    47  
    48 void make_height() {
    49     int i, j;
    50     for (i = j = 0; i < len; ++i) {
    51         if (j) --j;
    52         if (rank[i] != 1)
    53             while (a[i + j] == a[sa[rank[i] - 2] + j]) ++j;
    54         height[rank[i]] = j;
    55     }
    56 }
    57  
    58 ll work() {
    59     int i;
    60     ll res;
    61     static int s[N], top, l[N], r[N];
    62     for (res = 0, i = 1; i <= len; ++i) res += 1ll * i * (len - 1);
    63     for (s[top = 0] = 0, i = 1; i <= len; ++i) {
    64         while (height[i] <= height[s[top]] && top) --top;
    65         l[i] = s[top] + 1;
    66         s[++top] = i;
    67     }
    68     for (s[top = 0] = len + 1, i = len; i; --i) {
    69         while (height[i] < height[s[top]] && top) --top;
    70         r[i] = s[top] - 1;
    71         s[++top] = i;
    72     }
    73     for (i = 1; i <= len; ++i)
    74         res -= 2ll * (i - l[i] + 1) * (r[i] - i + 1) * height[i];
    75     return res;
    76 }
    77  
    78 int main() {
    79     int i;
    80     char ch;    
    81     for (len = 0; ;) {
    82         ch = getchar();
    83         if ('a' <= ch && ch <= 'z') a[len++] = ch - 'a' + 1;
    84         else break;
    85     }
    86     make_sa(a);
    87     make_height();
    88     printf("%lld
    ", work());
    89     return 0;
    90 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    Deep Learning(深度学习)学习笔记整理系列五
    Deep Learning(深度学习)学习笔记整理系列四
    Deep Learning(深度学习)学习笔记整理系列三
    Deep Learning(深度学习)学习笔记整理系列二
    Deep Learning(深度学习)学习笔记整理系列 一
    java对象转为json字符串
    eclipse常用功能及快捷键
    fiddler详解
    http状态码
    eclipse中文乱码
  • 原文地址:https://www.cnblogs.com/rausen/p/4474854.html
Copyright © 2020-2023  润新知