poj 1743

来源:互联网 发布:linux如何安装tgz 编辑:程序博客网 时间:2024/05/22 06:49

       题意:给n个数字的序列,输出具有相同变化的最长公共不重叠子串

      分析:由于是要求具有相同变化,因此先将序列前后相减,再利用后缀数组的height数组求解就行了。

代码如下:

#include <cstdio>#include <stack>#include <set>#include <iostream>#include <string>#include <vector>#include <queue>#include <list>#include <functional>#include <cstring>#include <algorithm>#include <cctype>#include <string>#include <map>#include <iomanip>#include <cmath>#define LL long long#define ULL unsigned long long#define SZ(x) (int)x.size()#define MP(a, b) make_pair(a, b)#define MS(arr, num) memset(arr, num, sizeof(arr))#define PB push_back#define F first#define S second#define ROP freopen("input.txt", "r", stdin);#define MID(a, b) (a + ((b - a) >> 1))#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define lrt rt << 1#define rrt rt << 1|1#define root 1,n,1#define BitCount(x) __builtin_popcount(x)#define BitCountll(x) __builtin_popcountll(x)#define LeftPos(x) 32 - __builtin_clz(x) - 1#define LeftPosll(x) 64 - __builtin_clzll(x) - 1const double PI = acos(-1.0);const int INF = 1e7;using namespace std;const double eps = 1e-5;const int MAXN = 300 + 10;const int MOD = 1000007;const double M=1e-8;const int N=int(2e5)+10;typedef pair<int, int> pii;typedef pair<int, string> pis;int cnt[N],wv[N],wa[N],wb[N];int sa[N],rank[N],height[N];bool cmp(int *y,int a,int b,int l){    return y[a]==y[b] && y[a+l]==y[b+l];}void da(int s[],int n,int m){     int i,j,p,*x=wa,*y=wb;     MS(cnt,0);     for (i=0;i<n;i++) cnt[x[i]=s[i]]++;     for (i=1;i<m;i++) cnt[i]+=cnt[i-1];     for (i=n-1;i>=0;i--) sa[--cnt[x[i]]]=i;     for (j=1,p=1;p<n;j<<=1,m=p) {  // m这里值有m个不同的rank[]值,是对下面基数排序的一个常数优化        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]];        MS(cnt,0);        for (i=0;i<n;i++) cnt[wv[i]]++;        for (i=1;i<m;i++) cnt[i]+=cnt[i-1];        for (i=n-1;i>=0;i--) sa[--cnt[wv[i]]]=y[i];        swap(x,y);        for (i=1,p=1,x[sa[0]]=0;i<n;i++) {      //   x[rank[i]]=i;            x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;        }     }     //rank=x;}void getHeight(int s[],int n)  // height[] 只有h[1]~h[n] 是有效数值,height[0]=0论意义的话是因为手动往s[]末尾添加了0{    int i,j,k=0;    for (i=1;i<=n;i++) rank[sa[i]]=i;    for (i=0;i<n;height[rank[i++]]=k) {        for (k?k--:0,j=sa[rank[i]-1];s[i+k]==s[j+k];k++) ;    }}vector<int> v[N];bool check(int k,int n){    if (k==0) return true;    int i,j,cur=-1;    for (i=1;i<=n;i++) {        if (height[i]<k) v[++cur].clear();        v[cur].push_back(i);    }    for (i=0;i<=cur;i++) {        int t=v[i].size(),mx=-1,mn=INF;        if (t<=1) continue;        for (j=0;j<t;j++) {            mn=min(mn,sa[ v[i][j] ]);            mx=max(mx,sa[ v[i][j] ]);        }        if (mx-mn>=k) return true;    }    return false;}int slove(int n){    int l=1,r=n,ans=0;    while(l<=r) {        int mid=MID(l,r);        if (check(mid,n)) ans=mid,l=mid+1;        else r=mid-1;    }    return ans>=4?ans+1:0;}int r[N];int main(){    int i,j,n;    while(~scanf("%d",&n),n)    {        for (i=0;i<n;i++) scanf("%d",r+i);        for (i=0;i<n-1;i++) r[i]=r[i+1]-r[i]+90;      //    for (i=0;i<n-1;i++) cout<<r[i]<<" "; cout<<endl;        if (n<10) {            puts("0");            continue;        }        r[--n]=0;        da(r,n+1,200);        getHeight(r,n);//        for (i=1;i<n;i++) cout<<sa[i]<<" "; cout<<endl;//        for (i=0;i<n-1;i++) cout<<rank[i]<<" "; cout<<endl;//        for (i=1;i<n;i++) cout<<height[i]<<" "; cout<<endl;        int ans=slove(n);        printf("%d\n",ans);    }}/*101 2 3 4 5 6 7 8 9 10*/


0 0
原创粉丝点击