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

    【题目分析】

        其实找最长的不重叠字串是很容易的,后缀数组+二分可以在nlogn的时间内解决。

        但是转调是个棘手的事情。

        其实只需要o(* ̄▽ ̄*)ブ差分就可以了。

        背板题。

    【代码】

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    
    #include <map>
    #include <set>
    #include <queue>
    #include <string>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    #define maxn 50005
    #define inf 0x3f3f3f3f
    #define F(i,j,k) for (int i=j;i<=k;++i)
    #define D(i,j,k) for (int i=j;i>=k;--i)
    
    void Finout()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
    //    freopen("out.txt","w",stdout);
        #endif
    }
    
    int Getint()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    
    struct SuffixArray{
    	int s[maxn];
    	int tmp[maxn],cnt[maxn],sa[maxn],rk[maxn],h[maxn];
    	void build(int n,int m)
    	{
    		int i,j,k;n++;
    		F(i,0,2*n+5) tmp[i]=sa[i]=rk[i]=h[i]=0;
    		F(i,0,m-1) cnt[i]=0;
    		F(i,0,n-1) cnt[rk[i]=s[i]]++;
    		F(i,1,m-1) cnt[i]+=cnt[i-1];
    		F(i,0,n-1) sa[--cnt[rk[i]]]=i;
    		for (k=1;k<=n;k<<=1)
    		{
    			F(i,0,n-1)
    			{
    				j=sa[i]-k;
    				if (j<0) j+=n;
    				tmp[cnt[rk[j]]++]=j;
    			}
    			sa[tmp[cnt[0]=0]]=j=0;
    			F(i,1,n-1)
    			{
    				if (rk[tmp[i]]!=rk[tmp[i-1]]||rk[tmp[i]+k]!=rk[tmp[i-1]+k]) cnt[++j]=i;
    				sa[tmp[i]]=j;
    			}
    			memcpy(rk,sa,n*sizeof(int));
    			memcpy(sa,tmp,n*sizeof(int));
    			if (j>=n-1) break;
    		}
    		for (j=rk[h[i=k=0]=0];i<n-1;++i,++k)
    			while (~k&&s[i]!=s[sa[j-1]+k]) h[j]=k--,j=rk[sa[j]+1];
    	}
    }arr;
    
    int N,a[maxn];
    
    bool test(int k,int n)
    {
    	int minn=arr.sa[1],maxx=arr.sa[1];
    	F(i,2,n)
    	{
    		if (arr.h[i]>=k&&i<n)
    		{
    			minn=min(arr.sa[i],minn);
    			maxx=max(arr.sa[i],maxx);
    			continue;
    		}
    		if (maxx-minn>=k) return true;
    		minn=arr.sa[i];
    		maxx=arr.sa[i];
    	}
    	return false;
    }
    
    int main()
    {
        Finout();
        while (scanf("%d",&N)!=EOF&&N)
        {
        	F(i,0,N-1) scanf("%d",&a[i]);
        	F(i,0,N-2) arr.s[i]=a[i]-a[i+1]+89;
        	arr.s[N-1]=0;
        	arr.build(N-1,200);
        	int l=3,r=(N-2)/2;
        	while (l<r)
        	{
        		int mid=(l+r)/2+1;
        		if (test(mid,N-1)) l=mid;
        		else r=mid-1;
    		}
    		printf("%d
    ",l<4?0:l+1);
    	}
    }
    

      

  • 相关阅读:
    CodeForces 681D Gifts by the List (树上DFS)
    UVa 12342 Tax Calculator (水题,纳税)
    CodeForces 681C Heap Operations (模拟题,优先队列)
    CodeForces 682C Alyona and the Tree (树上DFS)
    CodeForces 682B Alyona and Mex (题意水题)
    CodeForces 682A Alyona and Numbers (水题,数学)
    Virtualizing memory type
    页面跳转
    PHP Misc. 函数
    PHP 5 Math 函数
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6241326.html
Copyright © 2011-2022 走看看