zoukankan      html  css  js  c++  java
  • poj 3261 Milk Patterns 后缀树组

    题意:求可相交的重复k次串

    思路:后缀数组+二分

      1 #include<iostream>
    2 #include<cstring>
    3 #include<algorithm>
    4 using namespace std;
    5 #define MAXN 20001
    6 struct number
    7 {
    8 int num,id;
    9 };
    10 number a[MAXN];
    11 int b[MAXN];
    12 int suffix_array[MAXN];
    13 int cnt[MAXN];
    14 int tmp[MAXN];
    15 int rank[MAXN*2],oldrank[MAXN*2];
    16 int height[MAXN];
    17 int n,m;
    18 bool cmp(const number &x, const number &y)
    19 {
    20 return x.num<y.num;
    21 }
    22 void SuffixArray()
    23 {
    24 int i;
    25 memset(rank,0,sizeof(rank));
    26 sort(a+1,a+n+1,cmp); a[0].num=-1;
    27 int pre=0,j=0;
    28 for(i=1;i<=n;i++)
    29 {
    30 if(a[i].num==a[j].num) rank[a[i].id]=pre;
    31 else
    32 {
    33 pre++; j=i;
    34 rank[a[i].id]=pre;
    35 }
    36 }
    37 memset(oldrank,0,sizeof(oldrank));
    38 for(int l=1;l<=n;l*=2)
    39 {
    40 memset(cnt,0,sizeof(cnt));
    41 for(i=1;i<=n;i++) cnt[rank[i+l]]++;
    42 for(i=1;i<=n;i++) cnt[i]+=cnt[i-1];
    43 for(i=1;i<=n;i++) tmp[cnt[rank[i+l]]--]=i;
    44
    45 memset(cnt,0,sizeof(cnt));
    46 for(i=1;i<=n;i++) cnt[rank[tmp[i]]]++;
    47 for(i=1;i<=n;i++) cnt[i]+=cnt[i-1];
    48 for(i=n;i>0;i--) suffix_array[cnt[rank[tmp[i]]]--]=tmp[i];
    49
    50 memcpy(oldrank,rank,sizeof(rank));
    51 rank[suffix_array[1]]=1;
    52 int k=1;
    53 for(i=2;i<=n;i++)
    54 {
    55 int x=suffix_array[i-1],y=suffix_array[i];
    56 if(oldrank[x]!=oldrank[y]||oldrank[x+l]!=oldrank[y+l])
    57 k++;
    58 rank[y]=k;
    59 }
    60 if(k==n)break;
    61 }
    62 }
    63 void LCP()
    64 {
    65 int i,j;
    66 int k=0;
    67 for(i=1;i<=n;i++)
    68 {
    69 if(rank[i]==n)
    70 {
    71 height[n]=k=0;
    72 continue;
    73 }
    74 j=suffix_array[rank[i]+1];
    75 k=max(k-1,0);
    76 while(b[i+k]==b[j+k]) k++;
    77 height[rank[i]]=k;
    78 }
    79 }
    80 bool check(int mid)
    81 {
    82 int k=1;
    83 for(int i=1;i<n;i++)
    84 {
    85 if(height[i]>=mid)
    86 k++;
    87 else k=1;
    88 if(k>=m) return true;
    89 }
    90 return false;
    91 }
    92 int binary()
    93 {
    94 int left,right,mid;
    95 left=0; right=n;
    96 while(left<right)
    97 {
    98 mid=(left+right)/2;
    99 if(check(mid)) left=mid;
    100 else right=mid;
    101 if(right-left==1) return left;
    102 }
    103 }
    104 int main()
    105 {
    106 scanf("%d%d",&n,&m);
    107 int i;
    108 memset(a,0xff,sizeof(a));
    109 for(i=1;i<=n;i++)
    110 {
    111 scanf("%d",&a[i].num);
    112 a[i].id=i;
    113 b[i]=a[i].num;
    114 }
    115 SuffixArray();
    116 LCP();
    117 printf("%d\n",binary());
    118 return 0;
    119 }



  • 相关阅读:
    python 数据结构 图解递归 海龟画图分形树
    python 数据结构 理解迭代与递归 递归的实例 栈帧 函数调用
    python 数据结构 双端队列的两种实现方式 list 和 DoublelinkedList 回文词验证
    python 数据结构 实现队列的几种方法
    python 数据结构 实现链队的两种方法
    python 数据结构 查找数组最值
    python 数据结构 队列的实例 回文词与双端队列
    双向链表练习题
    均分纸牌问题
    L1-8 估值一亿的AI核心代码
  • 原文地址:https://www.cnblogs.com/myoi/p/2343525.html
Copyright © 2011-2022 走看看