zoukankan      html  css  js  c++  java
  • BZOJ 2882 工艺 (字符串最小循环同构)

    题目大意:

    给一个长度小于等于30W的数列,求其最小循环同构。

    算法讨论:

    在自动机长倍长走S后即可。注意这里面是数字,要用map存储。 今天才知道要开四倍长。

    Codes:

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 const int L = 300000 + 5;
      5 
      6 int n, a[L<<1], ans;
      7 
      8 struct State{
      9   int len, pre;
     10   map <int, int> next;
     11   
     12   State(){
     13     len = pre = 0;
     14     next.clear();
     15   }
     16   void clear(){
     17     len = pre = 0;
     18     next.clear();
     19   }
     20 }st[L<<1];
     21 
     22 struct SuffixAutomaton{
     23   int sz, last;
     24 
     25   void Init(){
     26     last = sz = 0;
     27     st[0].len = 0; st[0].pre = -1;
     28     sz ++;
     29   }
     30   void Extend(int c){
     31     int cur = sz ++;
     32     st[cur].len = st[last].len + 1;
     33     int p;
     34 
     35     for(p = last; p != -1 && !st[p].next[c]; p = st[p].pre)
     36       st[p].next[c] = cur;
     37 
     38     if(p == -1) st[cur].pre = 0;
     39     else{
     40       int q = st[p].next[c];
     41       if(st[q].len == st[p].len + 1) st[cur].pre = q;
     42       else{
     43         int cle = sz ++;
     44         st[cle].len = st[p].len + 1;
     45         st[cle].pre = st[q].pre;
     46         st[cle].next = st[q].next;
     47         for(; p != -1 && st[p].next[c] == q; p = st[p].pre)
     48           st[p].next[c] = cle;
     49         st[q].pre = st[cur].pre = cle;
     50       }
     51     }
     52     last = cur;
     53   }
     54 }SAM;
     55 
     56 void Input(){
     57   scanf("%d", &n);
     58   for(int i = 0; i < n; ++ i)
     59     scanf("%d", &a[i]);
     60 }
     61 void Output(){
     62   bool flag = false;
     63   for(int i = ans; i < ans + n; ++ i){
     64     if(!flag){
     65       flag = true;
     66       printf("%d", a[i % n]);
     67     }
     68     else
     69       printf(" %d", a[i % n]);
     70   }
     71     
     72   printf("
    ");
     73 }
     74 
     75 void Solve(){
     76   SAM.Init();
     77   for(int i = 0; i < n; ++ i)
     78     a[i + n] = a[i];
     79   for(int i = 0; i < (n<<1); ++ i)
     80     SAM.Extend(a[i]);
     81 
     82   int p = 0;
     83   map <int, int>:: iterator pos;
     84   
     85   for(int i = 0; i < n; ++ i){
     86     for(pos = st[p].next.begin(); pos != st[p].next.end(); ++ pos){
     87       p = (*pos).second;
     88       break;
     89     }
     90   }
     91 
     92   ans = st[p].len - n;
     93 }
     94 
     95 int main(){
     96 
     97   Input();
     98   Solve();
     99   Output();
    100 
    101   return 0;
    102 }
    BZOJ 2882
  • 相关阅读:
    命令执行顺序控制与管道
    js获取返回首页
    手机站点击商务通无轨迹解决方法
    js文字向上滚动代码
    文字隐藏多余的文字
    QQ弹窗代码
    百度推送代码
    js手机站跳转
    js 判断时间,满足执行框架
    js切换换class
  • 原文地址:https://www.cnblogs.com/sxprovence/p/5136391.html
Copyright © 2011-2022 走看看