zoukankan      html  css  js  c++  java
  • poj 1509

    求一个字符串在旋转置换群下最小字典表示。

    用的是后缀数组(后缀自动机还是再听听jason_yu讲讲吧,关于right集合的部分还有问题)

    最小表示法的思想很有好(判断两个对象在某一置换群划分下,是否等价,可以求出两个对象在该置换群划分下的最小表示,然后比较最小表示)

     1 #include <cstdio>
     2 #include <cstring>
     3 #define min(a,b) ((a)<(b)?(a):(b))
     4 #define N 20010
     5 
     6 int n, aa[N];
     7 int sa[N], rk[N], ht[N], vv[N];
     8 
     9 void expand( int *s, int *r, int *sa, int *rk, int k ) {
    10     for( int i=1; i<=n; i++ )
    11         vv[r[s[i]]]=i;
    12     for( int i=n; i>=1; i-- )
    13         if( s[i]>k ) sa[vv[r[s[i]-k]]--] = s[i]-k;
    14     for( int i=n-k+1; i<=n; i++ )
    15         sa[vv[r[i]]--] = i;
    16     for( int i=1; i<=n; i++ )
    17         rk[sa[i]] = rk[sa[i-1]]+(r[sa[i]]!=r[sa[i-1]]||r[sa[i]+k]!=r[sa[i-1]+k]);
    18 }
    19 void calcht() {
    20     for( int i=1,k=0; i<=n; i++ ) {
    21         if( rk[i]==1 ) {
    22             k = ht[i] = 0;
    23             continue;
    24         }
    25         int j=sa[rk[i]-1];
    26         while( aa[i+k]==aa[j+k] ) k++;
    27         ht[i] = k;
    28         if( k>0 ) k--;
    29     }
    30 }
    31 void suffix() {
    32     static int tsa[N], trk[N];
    33     for( int i=1; i<=26; i++ ) vv[i] = 0;
    34     for( int i=1; i<=n; i++ ) vv[aa[i]]++;
    35     for( int i=1; i<=26; i++ ) vv[i]+=vv[i-1];
    36     for( int i=n; i>=1; i-- ) sa[vv[aa[i]]--]=i;
    37     for( int i=1; i<=n; i++ )
    38         rk[sa[i]] = rk[sa[i-1]]+(aa[sa[i]]!=aa[sa[i-1]]);
    39     for( int k=1; k<n; k<<=1 ) {
    40         expand( sa, rk, tsa, trk, k );
    41         for( int i=1; i<=n; i++ )
    42             sa[i]=tsa[i], rk[i]=trk[i];
    43     }
    44     calcht();
    45 }
    46 int sov() {
    47     int nn = (n+1)>>1;
    48     for( int i=1; i<=n; i++ )
    49         if( n-sa[i]+1>=nn ) {
    50             int rt = sa[i];
    51             for( int j=i+1; j<=n && ht[sa[j]]>=nn; j++ ) 
    52                 rt = min( rt, sa[j] );
    53             return rt;
    54         }
    55     return -1;
    56 }
    57 int main() {
    58     int T;
    59     scanf( "%d", &T );
    60     while( T-- ) {
    61         static char buf[N];
    62         scanf( "%s", buf+1 );
    63         n = strlen( buf+1 );
    64         for( int i=1; i<=n; i++ )
    65             aa[i+n] = aa[i] = buf[i]-'a'+1;
    66         n += n;
    67         suffix();
    68         printf( "%d
    ", sov() );
    69     }
    70 }
    View Code
  • 相关阅读:
    用php做了下冒泡排序
    安装xampp无法设置默认时间的坑
    PHP的静态变量和引用函数
    jquery.cookie.js 用法
    PhpStorm的open in browser怎么修改端口和相对路径
    springmvc上传图片并显示图片--支持多图片上传
    Spring MVC中处理静态资源的多种方法
    超强、超详细Redis数据库入门教程(转载)
    推荐60个jQuery插件(转)
    [Spring MVC]
  • 原文地址:https://www.cnblogs.com/idy002/p/4449513.html
Copyright © 2011-2022 走看看