后缀数组 poj. 1743. Musial Theme
来源:互联网 发布:黑帽seo如何赚钱 编辑:程序博客网 时间:2024/06/07 04:46
题意感觉有点难懂。但就是问你,给你一个数字串,然后问有没有相同子串(不能重合且长度大于五),或者不用相同的,全部加上一个或减去一个数之后相等的就好。
先是二分长度,然后通过height数组来判断是否可行
#include <iostream>#include <cstring>#include <cstdio>#include <cmath>#include <algorithm>#include<string>using namespace std;const int maxn =4e4+10;int n;struct Suffix{ int s[maxn]; int SA[maxn],ranked[maxn],height[maxn]; int x[maxn],y[maxn],buc[maxn],len,m; void init(int *str) { //len=strlen(str); len=n; for(int i=0;i<len;i++) s[i]=(int)str[i]; m=200;// } void build() { for (int i = 0; i < m; i++) buc[i] = 0; // buc 是一个桶 for (int i = 0; i < len; i++) buc[x[i] = s[i]]++; for (int i = 1; i < m; i++) buc[i] += buc[i - 1]; for (int i = len - 1; i >= 0; i--) SA[--buc[x[i]]] = i; for (int k = 1; k <= len; k <<= 1) { // k 倍增 int p = 0; //对第二关键字排序,y[i]:第i大的第二关键字是谁 // 后缀 len - k 及之后的所有后缀第二关键字最小。为0 for (int i = len - 1; i >= len - k; i--) y[p++] = i; for (int i = 0; i < len; i++) if (SA[i] >= k) y[p++] = SA[i] - k; //总体来排个序,求出SA for (int i = 0; i < m; i++) buc[i] = 0; for (int i = 0; i < len; i++) buc[x[y[i]]]++; for (int i = 1; i < m; i++) buc[i] += buc[i - 1]; for (int i = len - 1; i >= 0; i--) SA[--buc[x[y[i]]]] = y[i]; swap(x, y); p = 1; x[SA[0]] = 0; // 重新计算每个一元的名次。则x数组里存的是总体的顺序 for (int i = 1; i < len; i++) { if (y[SA[i - 1]] == y[SA[i]] && y[SA[i - 1] + k] == y[SA[i] + k]) x[SA[i]] = p - 1; else x[SA[i]] = p++; } if (p >= len) break; // 每个后缀的名次已经完全不同,不需要继续倍增 m = p; // 更新名次的最大值。 } } void LCP() { for(int i=0;i<len;i++) ranked[SA[i]]=i; int k=0; for(int i=0;i<len;i++) { if(ranked[i]==0) {height[0]=0;continue;} if(k) k--; int j=SA[ranked[i]-1]; while(s[i+k]==s[j+k]&&i+k<len&&j+k<len) k++; height[ranked[i]]=k; } } /* int LCS(char *s1) { int l=strlen(s1); s1[l]=' '; scanf("%s",s1+l+1); init(s1); build(); LCP(); int ans=0; for(int i=1;i<len;i++) if((SA[i-1]<l&&SA[i]>l)||(SA[i-1]>l&&SA[i]<l)) ans=max(ans,height[i]); return ans; }*/};Suffix a;int ok(int mid){ int i=1; while(1){ for(;i<n;i++) if(a.height[i]>=mid) break; if(i>=n) break; int minn=a.SA[i-1]; int maxx=a.SA[i-1]; while(i<n&&a.height[i]>=mid) { minn=min(a.SA[i],minn); maxx=max(a.SA[i],maxx); i++; } if(maxx-minn>=mid) return 1; } return 0;}int num[maxn];int str[maxn];int main(){ while(scanf("%d",&n)!=EOF&&n) { memset(str,0,sizeof(str)); memset(num,0,sizeof(num)); for(int i=0;i<n;i++) scanf("%d",&num[i]); if(n<10) printf("0\n"); else { for(int i=1;i<n;i++) str[i-1]=num[i]-num[i-1]+100; n--; // str[n-1]=0; a.init(str); a.build(); a.LCP(); int l=4,r=n/2,res=0; while(l<=r) { int mid=l+(r-l)/2; if(ok(mid)){ res=mid; l=mid+1; } else r=mid-1; } if(res>=4) printf("%d\n",res+1); else printf("0\n"); } } return 0;}
阅读全文
0 0
- 后缀数组 poj. 1743. Musial Theme
- Musical Theme+POJ+后缀数组
- poj Musical Theme 后缀数组
- poj 1743 Musical Theme 后缀数组
- POJ 1743 Musical Theme 后缀数组
- poj 1743 Musical Theme 【后缀数组】
- poj 1743 Musical Theme 后缀数组
- POJ 1743 Musical Theme(后缀数组)
- POJ 1743 Musical Theme(后缀数组)
- poj 1743 Musical Theme 后缀数组
- poj 1743 Musical Theme(后缀数组)
- POJ 1743 Musical Theme (后缀数组)
- 【后缀数组】 POJ 1743 Musical Theme
- 【POJ 1743】Musical Theme【后缀数组】
- POJ 1743 Musical Theme 后缀数组
- [后缀数组+二分] poj 1743 Musical Theme
- 【后缀数组】【poj 1743】Musical Theme
- 【POJ】1743 Musical Theme 【后缀数组】
- web打印组件康虎云报表与odoo整合示例
- 关于多门编程语言的基本语句的展示(c++,后期再补充)
- Python网络编程--Echo服务
- RxJava2+Retrofit2精讲
- JavaScript实时校验用户输入
- 后缀数组 poj. 1743. Musial Theme
- Jmeter 跨线程组传递参数
- Educational Codeforces Round 22 A. The Contest
- JavaScript
- Zookeeper可以干什么
- c++迭代器失效问题
- Matlab中设置运行时间
- leetcode520. Detect Capital
- 数据持久化