poj1743 Musical Theme
Posted ws_ccd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj1743 Musical Theme相关的知识,希望对你有一定的参考价值。
神题!!
2333,要求可以给区间加减同一个数,然后我就懵逼了,,%%题解,可以用差分嘛2333
所以原来的区间长度差分之后就要减一了,
然后现在用sa搞出height数组,然后对于>=len(len为二分的答案长度-1)的区间,去里面sa的最大和最小的差,就是这两个子串相距的最远距离了,判断这个是不是满足>len就好
注意,不能==len,因为这是差分数组,==len的话就相当于重合
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #define N 100005 5 #define inf 0x3f3f3f3f 6 #define LL long long 7 #define eps 1e-8 8 using namespace std; 9 inline int ra() 10 { 11 int x=0,f=1; char ch=getchar(); 12 while (ch<‘0‘ || ch>‘9‘) {if (ch==‘-‘) f=-1; ch=getchar();} 13 while (ch>=‘0‘ && ch<=‘9‘) {x=x*10+ch-‘0‘; ch=getchar();} 14 return x*f; 15 } 16 17 int sa[2][N],rank[2][N],v[N],height[N]; 18 int p=0,q=1,n; 19 int a[N]; 20 21 void get_height() 22 { 23 int k=0; 24 for (int i=1; i<=n; i++) 25 { 26 if (rank[p][i]==1) height[1]=0; 27 else 28 { 29 int j=sa[p][rank[p][i]-1]; 30 while (a[i+k]==a[j+k]) k++; 31 height[rank[p][i]]=k; k?k--:k; 32 } 33 } 34 } 35 void cal_sa(int sa[N], int rank[N], int Sa[N], int Rank[N], int k) 36 { 37 for (int i=1; i<=n; i++) v[rank[sa[i]]]=i; 38 for (int i=n; i>=1; i--) if (sa[i]>k) Sa[v[rank[sa[i]-k]]--]=sa[i]-k; 39 for (int i=n-k+1; i<=n; i++) Sa[v[rank[i]]--]=i; 40 for (int i=1; i<=n; i++) Rank[Sa[i]]=Rank[Sa[i-1]]+(rank[Sa[i]]!=rank[Sa[i-1]] || rank[Sa[i]+k]!=rank[Sa[i-1]+k]); 41 } 42 void work() 43 { 44 for (int i=1; i<=n; i++) v[a[i]]++; 45 for (int i=1; i<=200; i++) v[i]+=v[i-1]; 46 for (int i=1; i<=n; i++) sa[p][v[a[i]]--]=i; 47 for (int i=1; i<=n; i++) rank[p][sa[p][i]]=rank[p][sa[p][i-1]]+(a[sa[p][i]]!=a[sa[p][i-1]]); 48 for (int k=1; k<n; k<<=1,swap(p,q)) cal_sa(sa[p],rank[p],sa[q],rank[q],k); 49 get_height(); 50 } 51 bool check(int len) 52 { 53 int mn=inf,mx=-inf; 54 for (int i=2; i<=n; i++) 55 { 56 if (height[i]>=len) 57 { 58 mx=max(mx,max(sa[p][i-1],sa[p][i])); 59 mn=min(mn,min(sa[p][i-1],sa[p][i])); 60 if (mx-mn>len) return 1; 61 } 62 else mn=inf,mx=-inf; 63 } 64 return 0; 65 } 66 void solve() 67 { 68 int l=0,r=n>>1,ans=0; 69 while (l<=r) 70 { 71 int mid=l+r>>1; 72 if (check(mid)) ans=mid,l=mid+1; else r=mid-1; 73 } 74 printf("%d\n",ans>=4?ans+1:0); 75 } 76 77 int main(int argc, char const *argv[]) 78 { 79 while (n=ra()) 80 { 81 int last; 82 memset(v,0,sizeof(v)); 83 for (int i=1; i<=n; i++) 84 { 85 int x=ra(); 86 if (i!=1) a[i-1]=x-last+100; 87 last=x; 88 } 89 n--; work(); 90 solve(); 91 } 92 return 0; 93 }
以上是关于poj1743 Musical Theme的主要内容,如果未能解决你的问题,请参考以下文章