zoukankan      html  css  js  c++  java
  • UVA 719 / POJ 1509 Glass Beads (最小表示法/后缀自动机)

    题目大意:

    给出一个长度为N的字符串,求其字典序最小的循环同构。

    N<=10W。

    算法讨论:

    算法一、最小表示法。定义题。

    算法二、后缀自动机。

    Codes:

      1 #include <iostream>
      2 #include <algorithm>
      3 #include <cstdlib>
      4 #include <cstdio>
      5 #include <cstring>
      6 #include <cassert>
      7 using namespace std;
      8 const int L = 10000 + 5;
      9 
     10 int ans = 0;
     11 char str[L<<2];
     12 
     13 struct State{
     14   int len, pre;
     15   int next[26];
     16 
     17   State(){
     18     len = pre = 0;
     19     memset(next, 0, sizeof next);
     20   }
     21   void clear(){
     22     len = pre = 0;
     23     memset(next, 0, sizeof next);
     24   }
     25 }st[L<<2];
     26 
     27 struct SuffixAutomaton{
     28   int sz, last;
     29 
     30   void Init(){
     31     last = 0;
     32     sz = 0;
     33     for(int i = 0; i < (L<<2); ++ i)
     34       st[i].clear();
     35     st[0].len = 0; st[0].pre = -1;
     36     sz ++;
     37   }
     38   void Extend(int c){
     39     int cur = sz ++;
     40     st[cur].len = st[last].len + 1;
     41     int p;
     42 
     43     for(p = last; p != -1 && !st[p].next[c]; p = st[p].pre)
     44       st[p].next[c] = cur;
     45 
     46     if(p == -1) st[cur].pre = 0;
     47     else{
     48       int q = st[p].next[c];
     49       if(st[q].len == st[p].len + 1) st[cur].pre = q;
     50       else{
     51         int cle = sz ++;
     52         st[cle].len = st[p].len + 1;
     53         st[cle].pre = st[q].pre;
     54         for(int i = 0; i < 26; ++ i) st[cle].next[i] = st[q].next[i];
     55         for(; p != -1 && st[p].next[c] == q; p = st[p].pre)
     56           st[p].next[c] = cle;
     57         st[q].pre = st[cur].pre = cle;
     58       }
     59     }
     60     last = cur;
     61   }
     62 }SAM;
     63 
     64 void Input(){
     65   scanf("%s", str);
     66 }
     67 
     68 void Output(){
     69   printf("%d
    ", ans);
     70 }
     71 
     72 void Solve(){
     73   int len = strlen(str);
     74   SAM.Init();
     75   for(int i = 0; i < len; ++ i)
     76     str[i + len] = str[i];
     77   for(int i = 0; i < (len<<1); ++ i){
     78     SAM.Extend(str[i] - 'a');
     79   }
     80 
     81   int p = 0;
     82   for(int i = 0; i < len; ++ i){
     83     for(int j = 0; j < 26; ++ j){
     84       if(st[p].next[j]){
     85         p = st[p].next[j];
     86         break;
     87       }
     88     }
     89   }
     90 
     91   ans = st[p].len - len + 1;
     92 }
     93 
     94 int main(){
     95   int t;
     96   scanf("%d", &t);
     97   while(t --){
     98     Input();
     99     Solve();
    100     Output();
    101   }
    102   return 0;
    103 }
    后缀自动机
  • 相关阅读:
    构造函数以及四种方法的调用
    函数声明与函数表达式的区别
    display:inline-block,block,inline的区别与用法
    SASS 使用(vs code)
    SASS 使用(安装)
    vue 学习笔记1 入门
    ES6学习5 字符串的扩展
    ES6学习4 变量的解构赋值
    es6 学习2 模板字符
    es6 学习1 let表示变量 、const表示常量 与 var 变量的区别
  • 原文地址:https://www.cnblogs.com/sxprovence/p/5135434.html
Copyright © 2011-2022 走看看