zoukankan      html  css  js  c++  java
  • poj 1743 Musical Theme 后缀数组

    题目链接

    做出公差后找出最长不重叠子序列的长度。

    后缀数组的模板, 二分长度k然后将height数组分组, 判断每一组内sa的最大值-sa的最小值是否大于等于k, 如果大于等于k则满足。

      1 #include <iostream>
      2 #include <vector>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <algorithm>
      6 #include <cmath>
      7 #include <map>
      8 #include <set>
      9 #include <string>
     10 #include <queue>
     11 #include <stack>
     12 #include <bitset>
     13 using namespace std;
     14 #define pb(x) push_back(x)
     15 #define ll long long
     16 #define mk(x, y) make_pair(x, y)
     17 #define lson l, m, rt<<1
     18 #define mem(a) memset(a, 0, sizeof(a))
     19 #define rson m+1, r, rt<<1|1
     20 #define mem1(a) memset(a, -1, sizeof(a))
     21 #define mem2(a) memset(a, 0x3f, sizeof(a))
     22 #define rep(i, n, a) for(int i = a; i<n; i++)
     23 #define fi first
     24 #define se second
     25 typedef pair<int, int> pll;
     26 const double PI = acos(-1.0);
     27 const double eps = 1e-8;
     28 const int mod = 1e9+7;
     29 const int inf = 1061109567;
     30 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
     31 const int maxn = 2e4+5;
     32 int sa[maxn];
     33 int t1[maxn],t2[maxn],c[maxn], a[maxn];
     34 int rankk[maxn],height[maxn];
     35 void build_sa(int s[],int n,int m)
     36 {
     37     int i,j,p,*x=t1,*y=t2;
     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(j=1;j<=n;j<<=1)
     43     {
     44         p=0;
     45         for(i=n-j;i<n;i++)y[p++]=i;
     46         for(i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j;
     47         for(i=0;i<m;i++)c[i]=0;
     48         for(i=0;i<n;i++)c[x[y[i]]]++;
     49         for(i=1;i<m;i++)c[i]+=c[i-1];
     50         for(i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i];
     51         swap(x,y);
     52         p=1;x[sa[0]]=0;
     53         for(i=1;i<n;i++)
     54             x[sa[i]]=y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+j]==y[sa[i]+j]?p-1:p++;
     55         if(p>=n)break;
     56         m=p;
     57     }
     58 }
     59 void getHeight(int s[],int n)
     60 {
     61     int i,j,k=0;
     62     for(i=0;i<=n;i++)rankk[sa[i]]=i;
     63     for(i=0;i<n;i++)
     64     {
     65         if(k)k--;
     66         j=sa[rankk[i]-1];
     67         while(s[i+k]==s[j+k])k++;
     68         height[rankk[i]]=k;
     69     }
     70 }
     71 int check(int mid, int n) {
     72     int maxx = sa[1], minn = sa[1];
     73     for(int i = 2; i<=n; i++) {
     74         if(height[i]<mid) {
     75             minn = maxx = sa[i];
     76         } else {
     77             minn = min(minn, sa[i]);
     78             maxx = max(maxx, sa[i]);
     79             if(maxx-minn>mid)
     80                 return 1;
     81         }
     82     }
     83     return 0;
     84 }
     85 int main()
     86 {
     87     int n, m;
     88     while(cin>>n&&n) {
     89         for(int i = 0; i<n; i++)
     90             scanf("%d", &a[i]);
     91         for(int i = 0; i<n-1; i++) {
     92             a[i] = a[i] - a[i+1] + 90;
     93         }
     94         a[n--] = 0;
     95         build_sa(a, n+1, 190);
     96         getHeight(a, n);
     97         int l = 1, r = n/2;
     98         while(l<=r) {
     99             int mid = l+r>>1;
    100             if(!check(mid, n)) {
    101                 r = mid-1;
    102             } else {
    103                 l = mid+1;
    104             }
    105         }
    106         if(l<5) {
    107             l = 0;
    108         }
    109         cout<<l<<endl;
    110     }
    111     return 0;
    112 }
  • 相关阅读:
    问答
    观看视频后的笔记
    处理json的常用方式
    通过excel模板文件根据数据库数据修改其中的单元格数据
    declare用法
    添加文件然后自动打开
    Mybatis之入门
    观察者模式
    职责链模式
    并发新构件之Exchanger:交换器
  • 原文地址:https://www.cnblogs.com/yohaha/p/5097464.html
Copyright © 2011-2022 走看看