zoukankan      html  css  js  c++  java
  • POJ3581 后缀数组

    http://poj.org/problem?id=3581

    这题说是给了N个数字组成的序列A1 A2 ..An 其中A1 大于其他的数字 , 现在要把序列分成三段并将每段分别反转求最小字典序

    以后还是老老实实用基数排序 用sort wa 了 一晚

    #include <iostream>
    #include <algorithm>
    #include <string.h>
    #include <cstdio>
    #include <vector>
    using namespace std;
    /* run this program using the console pauser or add your own getch, system("pause") or input loop */
    const int maxn =200005;
    struct SuffixArry
    {
        int c[maxn*2],t[maxn*2],t1[maxn*2],sa[maxn*2];
        void build(int n,int m,int *S)
        {
             int *x=t,*y=t1,i;
             for( i=0; i<m; i++)c[i]=0;
             for( i=0; i<n; i++)c[x[i]=S[i] ]++;
             for( i=1; i<m; i++)c[i]+=c[i-1];
             for( i=n-1; i>=0; i--)sa[ --c[ x[i] ] ]=i;
             int p;
             for(int k=1; k<=n; k<<=1 )
             { 
                p=0;
                for( i = n-k; i<n; i++)y[p++]=i;
                for( i=0; i<n; i++) if(sa[i]>=k)y[p++]=sa[i]-k;
                for( i=0; i<m; i++)c[ i ] =0 ;
                for( i=0 ; i<n; i++ )c[ x[ y[i] ] ]++;
                for( i=1; i<m; i++) c[i]+=c[i-1];
                for( i=n-1; i>=0; i--) sa[--c[ x[ y[i] ] ] ]=y[i];
                swap(x,y);
                p=1; x[ sa[ 0 ] ] = 0;
                for(int i=1; i<n; i++)
                 x[ sa[i] ] = y[ sa[i] ]== y[ sa[i-1] ]&& y[ sa[i]+k ]==y[sa[i-1]+k]?p-1:p++;
                if(p>=n)break;
                m=p;
             }
        }
        void clear(){
            memset(t,-1,sizeof(t));
            memset(t1,-1,sizeof(t1));
        }
    }T;
    int A[maxn],B[maxn],C[maxn],rev[maxn*2];
    void revercopy(int *a, int *b, int len)
    {
         for(int i=0; i<len; i++)
         { 
              b[i]=a[len-1-i];
         }
    }
    void rever(int *a, int len)
    {
          for(int i=0; i<len/2; i++ )
          {
               int t= a[i]; 
               a[i]=a[len-1-i];
               a[len-1-i]=t;
          }
    }
    int main(int argc, char *argv[]) {
        
         int n;
         scanf("%d",&n);
         for(int i=0; i<n; i++)
            {
              scanf("%d",&A[i]);
              B[i]=A[i];
            }
         sort(B,B+n);
         int L=unique(B,B+n)-B;
         for(int i=0; i<n; i++)
             {
                C[i]=lower_bound(B,B+L,A[i])-B;
             }
         int p1;
         T.clear();
         revercopy(C,rev,n);
         T.build(n,L,rev);
          
          for(int i=0; i<n; i++)
          {
               p1 = n-T.sa[i];
               if(p1>0&&n-p1>=2)break;
          }
          
          if(p1<1||n-p1<2)while(true){};
          int m= n-p1;
          revercopy(C+p1,rev,m); //for(int i=0; i<m; i++)printf("%d ",rev[i]);
          revercopy(C+p1,rev+m,m);//for(int i=0; i<m*2; i++)printf("%d ",rev[i]);
          T.build(m*2,L,rev);
          int p2;
          for(int i=0; i<m*2; i++)
          { 
              p2 = p1 + m - T.sa[ i ];
              if(p2>p1&&n-p2>=1)break;
          }
          if(p2<=p1||n-p2<1)while(true){
          };
          rever(A,p1);
          rever(A+p1,p2-p1);
          rever(A+p2,n-p2);
          for(int i=0; i<n; i++) printf("%d
    ",A[i]);
        return 0;
    }
    View Code
  • 相关阅读:
    CMY/CMYK 打印机色彩
    safe RGB colors
    人眼内的三类视锥细胞
    函数极限的定义
    Region的周长, 面积与紧凑程度
    Boundary Representations
    Boundary Following Algorithm
    Region Representaion and Description
    JavaSE编码试题强化练习5
    JavaSE编码试题强化练习4
  • 原文地址:https://www.cnblogs.com/Opaser/p/4496523.html
Copyright © 2011-2022 走看看