POJ 3294 Life Forms (后缀数组)

来源:互联网 发布:英克灵智医药软件 编辑:程序博客网 时间:2024/05/20 11:27

题目地址:POJ 3294
把所有字符串连在一块,并用一个从未出现的字符隔开,注意这个每两个之间的用来隔开的字符也不能重复,除非对1个的时候进行特判。
然后二分长度,然后判断这个长度下能否有出现次数超过n/2次的,可以对其分组然后hash判断。找出最大长度之后,再用同样的方法从头找一遍,然后把符合要求的输出、
代码如下:

#include <iostream>#include <string.h>#include <math.h>#include <queue>#include <algorithm>#include <stdlib.h>#include <map>#include <set>#include <stdio.h>#include <string>#include <time.h>using namespace std;#define LL long long#define pi acos(-1.0)#pragma comment(linker, "/STACK:1024000000")const int mod=9901;const int INF=0x3f3f3f3f;const double eqs=1e-9;const int MAXN=200000+300;int ha[200], dp[200];char st[101][2000];int wa[MAXN], wb[MAXN], wv[MAXN], ws1[MAXN], s[MAXN];int sa[MAXN], rk[MAXN], height[MAXN];int cmp(int *r, int a, int b, int l){        return r[a]==r[b]&&r[a+l]==r[b+l];}void getsa(int *r, int *sa, int n, int m){        int i, j, p, *x=wa, *y=wb, *t;        for(i=0; i<m; i++) ws1[i]=0;        for(i=0; i<n; i++) ws1[x[i]=r[i]]++;        for(i=1; i<m; i++) ws1[i]+=ws1[i-1];        for(i=n-1; i>=0; i--) sa[--ws1[x[i]]]=i;        for(j=1,p=1; p<n; j*=2,m=p) {                for(p=0,i=n-j; i<n; i++) y[p++]=i;                for(i=0; i<n; i++) if(sa[i]>=j) y[p++]=sa[i]-j;                for(i=0; i<n; i++) wv[i]=x[y[i]];                for(i=0; i<m; i++) ws1[i]=0;                for(i=0; i<n; i++) ws1[wv[i]]++;                for(i=1; i<m; i++) ws1[i]+=ws1[i-1];                for(i=n-1; i>=0; i--) sa[--ws1[wv[i]]]=y[i];                for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1; i<n; i++)                        x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;        }}void Calheight(int *r, int n){        int i, j, k=0;        for(i=1; i<=n; i++) rk[sa[i]]=i;        for(i=0; i<n; height[rk[i++]]=k) {                for(k?--k:0,j=sa[rk[i]-1]; r[i+k]==r[j+k]; k++) ;        }}int BS(int x, int n){        int low=0, high=n-1, mid, ans;        while(low<=high) {                mid=low+high>>1;                if(dp[mid]<=x) {                        ans=mid;                        low=mid+1;                } else high=mid-1;        }        return ans;}int main(){        int n, i, j, len, tmp, x, res, flag;        while(scanf("%d",&n)!=EOF&&n) {                tmp=0;                for(i=0; i<n; i++) {                        scanf("%s",st[i]);                        len=strlen(st[i]);                        dp[i]=tmp;                        for(j=0; j<len; j++) {                                s[tmp++]=st[i][j]-'a'+1;                        }                        s[tmp++]=27+i;                }                s[tmp]=0;                getsa(s,sa,tmp+1,200);                Calheight(s,tmp);                int low=1, high=1000, mid, ans=-1;                while(low<=high) {                        mid=low+high>>1;                        memset(ha,0,sizeof(ha));                        res=0;                        for(i=1; i<=tmp; i++) {                                if(height[i]>=mid) {                                        x=BS(sa[i],n);                                        if(!ha[x]){                                                res++;                                                ha[x]=1;                                        }                                        x=BS(sa[i-1],n);                                        if(!ha[x]) {                                                res++;                                                ha[x]=1;                                        }                                        if(res>n/2) break;                                } else {                                        memset(ha,0,sizeof(ha));                                        res=0;                                }                        }                        if(i<=tmp) {                                ans=mid;                                low=mid+1;                        } else high=mid-1;                }                if(ans==-1) {                        puts("?\n");                        continue ;                }                memset(ha,0,sizeof(ha));                res=0;                flag=0;                for(i=1; i<=tmp; i++) {                        if(height[i]>=ans) {                                x=BS(sa[i],n);                                if(!ha[x]) {                                        res++;                                        ha[x]=1;                                }                                x=BS(sa[i-1],n);                                if(!ha[x]) {                                        res++;                                        ha[x]=1;                                }                                if(res>n/2&&!flag){                                        x=BS(sa[i],n);                                        for(j=sa[i]-dp[x];j<sa[i]+ans-dp[x];j++){                                                printf("%c",st[x][j]);                                        }                                        puts("");                                        flag=1;                                }                        } else {                                memset(ha,0,sizeof(ha));                                res=0;                                flag=0;                        }                }                puts("");        }        return 0;}
1 0
原创粉丝点击