• POJ3261 Milk Patterns 后缀数组


      题目链接:http://poj.org/problem?id=3261

        求可重叠的至少出现K次的最长公共前缀。

      先用后缀数组求出height数组,然后二分答案。

      1 //STATUS:C++_AC_47MS_720KB
      2 #include<stdio.h>
      3 #include<stdlib.h>
      4 #include<string.h>
      5 #include<math.h>
      6 #include<iostream>
      7 #include<string>
      8 #include<algorithm>
      9 #include<vector>
     10 #include<queue>
     11 #include<stack>
     12 #include<map>
     13 using namespace std;
     14 #define LL long long
     15 #define pii pair<int,int>
     16 #define Max(a,b) ((a)>(b)?(a):(b))
     17 #define Min(a,b) ((a)<(b)?(a):(b))
     18 #define mem(a,b) memset(a,b,sizeof(a))
     19 #define lson l,mid,rt<<1
     20 #define rson mid+1,r,rt<<1|1
     21 #define PI acos(-1.0)
     22 const int N=20010,INF=0x3f3f3f3f,MOD=10000,STA=8000010;
     23 const LL LNF=0x3f3f3f3f3f3f3f3f;
     24 const double DNF=1e13;
     25 //
     26 void swap(int& a,int& b){int t=a;a=b;b=t;}
     27 void swap(LL& a,LL& b){LL t=a;a=b;b=t;}
     28 //
     29 
     30 int num[N];
     31 int sa[N],t1[N],t2[N],c[N],rank[N],height[N],ma[1000010];
     32 int n,K,m;
     33 
     34 void build_sa(int s[],int n,int m)
     35 {
     36     int i,k,p,*x=t1,*y=t2;
     37     //第一轮基数排序
     38     for(i=0;i<m;i++)c[i]=0;
     39     for(i=0;i<n;i++)c[x[i]=s[i]]++;
     40     for(i=1;i<m;i++)c[i]+=c[i-1];
     41     for(i=n-1;i>=0;i--)sa[--c[x[i]]]=i;
     42     for(k=1;k<=n;k<<=1){
     43         p=0;
     44         //直接利用sa数组排序第二关键字
     45         for(i=n-k;i<n;i++)y[p++]=i;
     46         for(i=0;i<n;i++)if(sa[i]>=k)y[p++]=sa[i]-k;
     47         //基数排序第一关键字
     48         for(i=0;i<m;i++)c[i]=0;
     49         for(i=0;i<n;i++)c[x[y[i]]]++;
     50         for(i=1;i<m;i++)c[i]+=c[i-1];
     51         for(i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i];
     52         //根据sa和x数组计算新的x数组
     53         swap(x,y);
     54         p=1;x[sa[0]]=0;
     55         for(i=1;i<n;i++)
     56             x[sa[i]]=y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
     57         if(p>=n)break;   //已经排好序,直接退出
     58         m=p;     //下次基数排序的最大值
     59     }
     60 }
     61 
     62 void getHeight(int s[],int n)
     63 {
     64     int i,j,k=0;
     65     for(i=0;i<=n;i++)rank[sa[i]]=i;
     66     for(i=0;i<n;i++){
     67         if(k)k--;
     68         j=sa[rank[i]-1];
     69         while(s[i+k]==s[j+k])k++;
     70         height[rank[i]]=k;
     71     }
     72 }
     73 
     74 int binary(int l,int r)
     75 {
     76     int i,j,ok,mid,ret,cnt;
     77     while(l<r){
     78         mid=(l+r)>>1;
     79         ok=0;cnt=1;
     80         for(i=2;i<=n;i++){
     81             if(height[i]>=mid){
     82                 cnt++;
     83             }
     84             else {
     85                 if(cnt>=K){ok=1;break;}
     86                 cnt=1;
     87             }
     88         }
     89         if(cnt>=K)ok=1;
     90         if(ok){ret=mid,l=mid+1;}
     91         else r=mid;
     92     }
     93     return ret;
     94 }
     95 
     96 
     97 int main()
     98 {
     99  //   freopen("in.txt","r",stdin);
    100     int i,j,hig;
    101     while(~scanf("%d%d",&n,&K))
    102     {
    103         for(i=0;i<n;i++){
    104             scanf("%d",&num[i]);
    105             c[i]=num[i];
    106         }
    107         sort(c,c+n);
    108         for(i=j=0;i<n;i++){
    109             c[++j]=c[i];
    110             while(c[i]==c[j])i++;
    111             i--;
    112         }
    113         for(i=1;i<=j;i++)ma[c[i]]=i;
    114         for(i=0;i<n;i++)num[i]=ma[num[i]];
    115         num[n]=0;
    116         m=j+1;
    117 
    118         build_sa(num,n+1,m);
    119         getHeight(num,n);
    120 
    121         printf("%d\n",binary(0,n));
    122     }
    123     return 0;
    124 }
  • 相关阅读:
    python全栈学习--day39(multiprocess模块)
    python全栈学习--day38(多进程在python中的操作)
    python全栈学习--day36(socket验证客户端的合法性、 并发编程)
    python全栈学习--day35(黏包机制)
    python全栈学习--day33(网络编程-socket)
    python-sys模块
    python-os模块
    python-生成随机数random
    python-常用模块-time、datetime模块
    python-模块、包
  • 原文地址:https://www.cnblogs.com/zhsl/p/3031425.html
Copyright © 2020-2023  润新知