zoukankan      html  css  js  c++  java
  • 洛谷-P3809-后缀排序(后缀数组)

    看了求后缀数组的倍增法之后很快就理解了,但是自己写的倍增法用map排序还是超时了。然后看了两天别人写的模板,题目是通过了,但感觉代码还是半懂半背的。以后多熟悉熟悉吧;

    • 后缀数组
      #include "bits/stdc++.h"
      using namespace std;
      const int MAXN = 1e6 + 5;
      char s[MAXN];
      int sa[MAXN], rk[MAXN], height[MAXN];
      void getSa(char* s, int* sa, int n, int m) {
          int* x = (int*)calloc(MAXN, sizeof(int));
          int* y = (int*)calloc(MAXN, sizeof(int));
          int* cnt = (int*)calloc(MAXN, sizeof(int));
          for (int i = 1; i <= n; i++) {
              cnt[x[i] = s[i]]++;
          }
          for (int i = 2; i <= m; i++) {
              cnt[i] += cnt[i - 1];
          }
          for (int i = n; i; i--) {
              sa[cnt[x[i]]--] = i;
          }
          for (int j = 1; j < n; j <<= 1) {
              int num = 0;
              for (int i = n - j + 1; i <= n; i++) {
                  y[++num] = i;
              }
              for (int i = 1; i <= n; i++) {
                  if (sa[i] > j) {
                      y[++num] = sa[i] - j;
                  }
              }
              for (int i = 1; i <= m; i++) {
                  cnt[i] = 0;
              }
              for (int i = 1; i <= n; i++) {
                  cnt[x[i]]++;
              }
              for (int i = 2; i <= m; i++) {
                  cnt[i] += cnt[i - 1];
              }
              for (int i = n; i; i--) {
                  sa[cnt[x[y[i]]]--] = y[i];
              }
              swap(x, y);
              x[sa[1]] = num = 1;
              for (int i = 2; i <= n; i++) {
                  if (y[sa[i]] != y[sa[i - 1]] || y[sa[i] + j] != y[sa[i - 1] + j]) {
                      x[sa[i]] = ++num;
                  } else {
                      x[sa[i]] = num;
                  }
              }
              if (num >= n) {
                  break;
              }
              m = num;
          }
          free(x);
          free(y);
          free(cnt);
      }
      void getHeight(char* s, int* sa, int* rk, int* height, int n) {
          for (int i = 1; i <= n; i++) {
              rk[sa[i]] = i;
          }
          int k = 0;
          for (int i = 1; i <= n; i++) {
              k = k != 0 ? k - 1 : k;
              int j = sa[rk[i] - 1];
              while (s[i + k] == s[j + k]) {
                  k++;
              }
              height[rk[i]] = k;
          }
      }
      int main() {
          gets(s + 1);
          int len = strlen(s + 1);
          getSa(s, sa, len, 130);
          // getHeight(s, sa, rk, height, len);
          for (int i = 1; i < len; i++) {
              printf("%d ", sa[i]);
          }
          printf("%d
      ", sa[len]);
          /*
          for (int i = 1; i < len; i++) {
              printf("%d ", rk[i]);
          }
          printf("%d
      ", rk[len]);
          for (int i = 1; i < len; i++) {
              printf("%d ", height[i]);
          }
          printf("%d
      ", height[len]);
          */
          return 0;
      }

      附带rank数组和height数组,本题不需要。

  • 相关阅读:
    2、容器初探
    3、二叉树:先序,中序,后序循环遍历详解
    Hebbian Learning Rule
    论文笔记 Weakly-Supervised Spatial Context Networks
    在Caffe添加Python layer详细步骤
    论文笔记 Learning to Compare Image Patches via Convolutional Neural Networks
    Deconvolution 反卷积理解
    论文笔记 Feature Pyramid Networks for Object Detection
    Caffe2 初识
    论文笔记 Densely Connected Convolutional Networks
  • 原文地址:https://www.cnblogs.com/Angel-Demon/p/10321816.html
Copyright © 2011-2022 走看看