POJ2774 & 后缀数组模板题
题意:
求两个字符串的LCP
SOL:
模板题.连一起搞一搞就好了...主要是记录一下做(sha)题(bi)过程心(cao)得(dan)体(xin)会(qing)
后缀数组概念...还算是简单的,过程也非常清晰...就是老人家...马丹代码那么写意真的是...每一句代码的意思大概都知道但是不能很准确的描述...自己实现又漏洞百出...所以虽然避免了抄模板...但还是相当于一个默写的过程...
然后这个题目...非常显然嘛不是...然后就打了...然后开始调...TLE...TLE...TLE...日了狗了...
然后对拍,发现有bug,那么就gdb...
然后发现不行,代码改的看不懂了.
然后推倒重来...反正多默写一遍多熟悉一点... 然后... TLE...
什么鬼啊!!!!
然后觉得什么都没什么问题...然后开始改读入... RE...
然后继续改读入... 因为一个终端跑着10w数据的对拍巨卡无比
然后在卡死的边缘交了一发
卡着卡着就绿了...
日了狗了啊woc!
然而写出来还是慢了很多...
然后才发现貌似原来用scanf的时候一直在调用strlen...
算了算了不想改回去测了...
什么jb! 我一天就调了这么一道题...
我可以假装说我对后缀数组的理解更深了一步.
什么鬼啊!!!!!
然后贴一张令人崩溃的图.
随处可见效率比我高的代码,但还是要贴一贴.
Code:
/*========================================================================== # Last modified: 2016-03-14 17:47 # Filename: poj2774.cpp # Description: ==========================================================================*/ #define me AcrossTheSky #include <cstdio> #include <cmath> #include <ctime> #include <string> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include <set> #include <map> #include <stack> #include <queue> #include <vector> #define lowbit(x) (x)&(-x) #define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++) #define FORP(i,a,b) for(int i=(a);i<=(b);i++) #define FORM(i,a,b) for(int i=(a);i>=(b);i--) #define ls(a,b) (((a)+(b)) << 1) #define rs(a,b) (((a)+(b)) >> 1) #define getlc(a) ch[(a)][0] #define getrc(a) ch[(a)][1] #define maxn 200000 #define maxm 100000 #define pi 3.1415926535898 #define _e 2.718281828459 #define INF 1070000000 using namespace std; typedef long long ll; typedef unsigned long long ull; template<class T> inline void read(T& num) { bool start=false,neg=false; char c; num=0; while((c=getchar())!=EOF) { if(c=='-') start=neg=true; else if(c>='0' && c<='9') { start=true; num=num*10+c-'0'; } else if(start) break; } if(neg) num=-num; } /*==================split line==================*/ //char temp1[maxn],temp[maxn]; int s[maxn]; int t[maxn],t2[maxn],c[100],rank[maxn],sa[maxn]; int height[maxn]; int n; void build_sa(int m){ int *x=t,*y=t2; //memset(c,0,sizeof(c)); FORP(i,0,m) c[i]=0; FORP(i,0,n-1) c[x[i]=s[i]]++; FORP(i,1,m-1) c[i]+=c[i-1]; FORM(i,n-1,0) sa[--c[x[i]]]=i; for (int k=1;k<=n;k <<= 1){ int p=0; FORP(i,n-k,n-1) y[p++]=i; FORP(i,0,n-1) if (sa[i]>=k) y[p++]=sa[i]-k; FORP(i,0,m) c[i]=0; FORP(i,0,n-1) c[x[y[i]]]++; FORP(i,1,m-1) c[i]+=c[i-1]; FORM(i,n-1,0) sa[--c[x[y[i]]]]=y[i]; swap(x,y); p=1; x[sa[0]]=0; FORP(i,1,n-1) 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>=n) break; m=p; } } void getheight(){ int k=0; FORP(i,0,n-1) rank[sa[i]]=i; FORP(i,0,n-1){ if (k) k--; int j=sa[rank[i]-1]; while (s[i+k] == s[j+k]) k++; height[rank[i]]=k; } } int main(){ //s[strlen(s)]='`'; char ch; while ((ch=getchar())>='a' && ch<='z') s[n++]=ch-'a'+1; s[n]=0; int len=n-1; n++; while ((ch=getchar())!=EOF && ch>='a' && ch<='z') s[n++]=ch-'a'+1; s[n]=29; n++; build_sa(30); getheight(); int ans=0; FORP(i,1,n-1){ if (height[i]>ans){ if (sa[i-1]<len && sa[i]>=len) ans=max(height[i],ans); if(sa[i-1]>=len && sa[i]<len) ans=max(height[i],ans); } } printf("%d\n",ans); }
Sometimes it s the very people who no one imagines anything of. who do the things that no one can imagine.