spoj LCS
Posted gaudar
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spoj LCS相关的知识,希望对你有一定的参考价值。
解法1:后缀自动机
解法1.1用串1建后缀自动机,用串2匹配。并记录能匹配的长度。匹配成功+1,否则变为maxlen[最后fail到的位置]+1。
解法1.2串一先加,然后加入‘#‘。再加串2.加串2的时候,如果新得到的节点的slink在一串,则说明出现了2次。
解法1.3.建立广义后缀自动机,用数组记录各节点出现在哪个串,在拓扑排序。然后出现2次的maxlen最大值就是。
解法2:2分+HASH。会超时。
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <iomanip> #include <cstring> #include <map> #include <queue> #include <set> #include <cassert> #include <stack> #include <bitset> //#include <unordered_set> #define mkp make_pair #define err cout<<"here"<<endl using namespace std; const double EPS=1e-12; typedef long long lon; typedef unsigned long long ull; typedef map<ull,int>::iterator IT; const lon SZ=500010,SSZ=120,APB=26,mod=97,one=1; const lon INF=0x7FFFFFFF; int n,cnt,nex[SZ][APB],fail[SZ]; int maxlen[SZ],minlen[SZ],trans[SZ][APB],slink[SZ]; struct nd{ int to,wt; nd(int a=0,int b=0):to(a),wt(b){} }; char ch1[SZ],ch2[SZ]; int add(int pre,int cur) { int z=++cnt; int u=pre; for(;u!=-1&&!trans[u][cur];u=slink[u]) { trans[u][cur]=z; } if(u==-1) { maxlen[z]=maxlen[pre]+1; minlen[z]=1; slink[z]=0; } else { int x=trans[u][cur]; if(maxlen[x]==maxlen[u]+1) { maxlen[z]=maxlen[pre]+1; minlen[z]=maxlen[x]+1; slink[z]=x; } else { int y=++cnt; memcpy(trans[y],trans[x],sizeof(trans[x])); maxlen[y]=maxlen[u]+1; minlen[y]=maxlen[slink[x]]+1; slink[y]=slink[x]; maxlen[x]=maxlen[x]; minlen[x]=maxlen[y]+1; slink[x]=y; maxlen[z]=maxlen[pre]+1; minlen[z]=maxlen[y]+1; slink[z]=y; for(;u!=-1&&trans[u][cur]==x;u=slink[u]) { trans[u][cur]=y; } } } return z; } void init() { cin>>ch1+1>>ch2+1; int pre=0; slink[0]=-1; for(int i=1;ch1[i];++i) { pre=add(pre,ch1[i]-‘a‘); } } int get_nex(int sta,int c,int &len) { int u=sta; if(trans[u][c]) {++len; return trans[u][c]; } for(;u!=-1&&!trans[u][c];) { u=slink[u]; //if(u!=-1)len=min(len,maxlen[u]); } if(u==-1)u=0,len=0; else len=maxlen[u]+1,u=trans[u][c]; return u; } void work() { int cur=0,res=0,len=0; for(int i=1;ch2[i];++i) { int c=ch2[i]-‘a‘; cur=get_nex(cur,c,len); res=max(res,len); //cout<<len<<endl; } cout<<res<<endl; } void release() { } int main() { std::ios::sync_with_stdio(0); //freopen("d:\\1.txt","r",stdin); int casenum; //cin>>casenum; //cout<<casenum<<endl; //for(int time=1;time<=casenum;++time) //for(int time=1;cin>>ch+1,ch[1]!=‘e‘;++time) { init(); work(); release(); } return 0; }
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <iomanip> #include <cstring> #include <map> #include <queue> #include <set> #include <cassert> #include <stack> #include <bitset> //#include <unordered_set> #define mkp make_pair #define err cout<<"here"<<endl using namespace std; const double EPS=1e-12; typedef long long lon; typedef unsigned long long ull; typedef map<ull,int>::iterator IT; const lon SZ=1000010,SSZ=120,APB=27,mod=97,one=1; const lon INF=0x7FFFFFFF; int n,cnt,num,nex[SZ][APB],fail[SZ],ans; int maxlen[SZ],minlen[SZ],trans[SZ][APB],slink[SZ]; struct nd{ int to,wt; nd(int a=0,int b=0):to(a),wt(b){} }; char ch1[SZ],ch2[SZ]; bool ok; int add(int pre,int cur) { int z=++cnt; int u=pre; for(;u!=-1&&!trans[u][cur];u=slink[u]) { trans[u][cur]=z; } if(u==-1) { maxlen[z]=maxlen[pre]+1; minlen[z]=1; slink[z]=0; } else { int x=trans[u][cur]; if(maxlen[x]==maxlen[u]+1) { maxlen[z]=maxlen[pre]+1; minlen[z]=maxlen[x]+1; slink[z]=x; if(ok&&x<=num)ans=max(ans,maxlen[x]); } else { int y=++cnt; memcpy(trans[y],trans[x],sizeof(trans[x])); maxlen[y]=maxlen[u]+1; minlen[y]=maxlen[slink[x]]+1; slink[y]=slink[x]; maxlen[x]=maxlen[x]; minlen[x]=maxlen[y]+1; slink[x]=y; maxlen[z]=maxlen[pre]+1; minlen[z]=maxlen[y]+1; slink[z]=y; for(;u!=-1&&trans[u][cur]==x;u=slink[u]) { trans[u][cur]=y; } if(ok&&x<=num)ans=max(ans,maxlen[y]); } } return z; } void init() { cin>>ch1+1>>ch2+1; int pre=0; slink[0]=-1; for(int i=1;ch1[i];++i) { pre=add(pre,ch1[i]-‘a‘); } pre=add(pre,26); ok=1; num=cnt; for(int i=1;ch2[i];++i) { pre=add(pre,ch2[i]-‘a‘); } cout<<ans<<endl; } void work() { } void release() { } int main() { std::ios::sync_with_stdio(0); //freopen("d:\\1.txt","r",stdin); int casenum; //cin>>casenum; //cout<<casenum<<endl; //for(int time=1;time<=casenum;++time) //for(int time=1;cin>>ch+1,ch[1]!=‘e‘;++time) { init(); work(); release(); } return 0; }
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <iomanip> #include <cstring> #include <map> #include <queue> #include <set> #include <cassert> #include <stack> #include <bitset> //#include <unordered_set> #define mkp make_pair #define err cout<<"here"<<endl using namespace std; const double EPS=1e-12; typedef long long lon; typedef unsigned long long ull; typedef map<ull,int>::iterator IT; const lon SZ=1000010,SSZ=120,APB=27,mod=97,one=1; const lon INF=0x7FFFFFFF; int n,cnt,nex[SZ][APB],fail[SZ]; int maxlen[SZ],minlen[SZ],trans[SZ][APB],slink[SZ]; struct nd{ int to,wt; nd(int a=0,int b=0):to(a),wt(b){} }; char ch1[SZ],ch2[SZ]; int sta[SZ],in[SZ]; int add(int pre,int cur,int num) { if(trans[pre][cur]) { int u=trans[pre][cur]; if(maxlen[u]==maxlen[pre]+1) { sta[u]|=1<<num; return u; } else { int z=++cnt; memcpy(trans[z],trans[u],sizeof(trans[u])); maxlen[z]=maxlen[pre]+1; slink[z]=slink[u]; slink[u]=z; minlen[z]=maxlen[slink[z]]+1; minlen[u]=maxlen[z]+1; sta[z]|=1<<num; return z; } } int z=++cnt; int u=pre; for(;u!=-1&&!trans[u][cur];u=slink[u]) { trans[u][cur]=z; } if(u==-1) { maxlen[z]=maxlen[pre]+1; minlen[z]=1; slink[z]=0; } else { int x=trans[u][cur]; if(maxlen[x]==maxlen[u]+1) { maxlen[z]=maxlen[pre]+1; minlen[z]=maxlen[x]+1; slink[z]=x; } else { int y=++cnt; memcpy(trans[y],trans[x],sizeof(trans[x])); sta[y]=sta[x]; maxlen[y]=maxlen[u]+1; minlen[y]=maxlen[slink[x]]+1; slink[y]=slink[x]; maxlen[x]=maxlen[x]; minlen[x]=maxlen[y]+1; slink[x]=y; maxlen[z]=maxlen[pre]+1; minlen[z]=maxlen[y]+1; slink[z]=y; for(;u!=-1&&trans[u][cur]==x;u=slink[u]) { trans[u][cur]=y; } } } sta[z]|=1<<num; return z; } void topo() { for(int i=1;i<=cnt;++i) { ++in[slink[i]]; } queue<int> q; for(int i=1;i<=cnt;++i) { if(in[i]==0) { q.push(i); } } for(;q.size();) { int fr=q.front(); q.pop(); int x=slink[fr]; --in[x]; sta[x]|=sta[fr]; if(in[x]==0&&x) { q.push(x); } } } void init() { cin>>ch1+1>>ch2+1; int pre=0; slink[0]=-1; for(int i=1;ch1[i];++i) { pre=add(pre,ch1[i]-‘a‘,0); } pre=0; for(int i=1;ch2[i];++i) { pre=add(pre,ch2[i]-‘a‘,1); } topo(); } void work() { int res=0; for(int i=1;i<=cnt;++i) { if(sta[i]==3)res=max(res,maxlen[i]); } cout<<res<<endl; } void release() { } int main() { std::ios::sync_with_stdio(0); //freopen("d:\\1.txt","r",stdin); int casenum; //cin>>casenum; //cout<<casenum<<endl; //for(int time=1;time<=casenum;++time) //for(int time=1;cin>>ch+1,ch[1]!=‘e‘;++time) { init(); work(); release(); } return 0; }
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <iomanip> #include <cstring> #include <map> #include <queue> #include <set> #include <cassert> #include <stack> #include <bitset> //#include <unordered_set> #define mkp make_pair #define err cout<<"here"<<endl using namespace std; const double EPS=1e-12; typedef long long lon; typedef unsigned long long ull; typedef map<ull,int>::iterator IT; const lon SZ=250010,SSZ=120,APB=26,mod=97,one=1; const lon INF=0x7FFFFFFF; int n; struct nd{ int to,wt; nd(int a=0,int b=0):to(a),wt(b){} }; char ch1[SZ],ch2[SZ]; ull arr[SZ]; bool chk(int x) { vector<ull> st; ull cur=0; for(int i=1;ch1[i];++i) { if(i<=x) { cur=cur*mod+ch1[i]; } else { cur=cur-arr[x-1]*ch1[i-x]; cur=cur*mod+ch1[i]; } if(i>=x)st.push_back(cur); } cur=0; sort(st.begin(),st.end()); for(int i=1;ch2[i];++i) { if(i<=x) { cur=cur*mod+ch2[i]; } else { cur=cur-arr[x-1]*ch2[i-x]; cur=cur*mod+ch2[i]; } if(i>=x&&*lower_bound(st.begin(),st.end(),cur)==cur)return 1; } return 0; } void init() { //cin>>ch1+1>>ch2+1; scanf(" %s %s",ch1+1,ch2+1); int len=strlen(ch1+1); arr[1]=mod; for(int i=2;i<len+5;++i) { if(i&1)arr[i]=arr[i/2]*arr[i/2]*mod; else arr[i]=arr[i/2]*arr[i/2]; } int lo=1,hi=strlen(ch1+1)+1; for(;lo<hi;) { int mid=(lo+hi)/2; bool ok=chk(mid); if(ok)lo=mid+1; else hi=mid; } cout<<lo-1<<endl; } void work() { } void release() { } int main() { //std::ios::sync_with_stdio(0); //freopen("d:\\1.txt","r",stdin); int casenum; //cin>>casenum; //cout<<casenum<<endl; //for(int time=1;time<=casenum;++time) //for(int time=1;cin>>ch+1,ch[1]!=‘e‘;++time) { init(); work(); release(); } return 0; }
以上是关于spoj LCS的主要内容,如果未能解决你的问题,请参考以下文章