Pagini recente » Muzica | Cod sursa (job #115870) | Cod sursa (job #135967) | Cod sursa (job #2070517) | Cod sursa (job #3149761)
#include <iostream>
#include <fstream>
#include <cstring>
#include <algorithm>
#define nmax 16390
#define logmax 15
using namespace std;
char s[nmax];
int dp[logmax][nmax];///dp[i][j]=pozitia prefixului de lungime 2^i ce incepe pe pozitia j in sirul subsecventelor de lungime 2^i sortate
struct aux{
int poz;
int r[2];
};
aux l[nmax];
struct sufix{
int pozitie;
int index;
};
sufix v[nmax];
int n,k,lg,ans;
ifstream f("substr.in");
ofstream g("substr.out");
bool cmp(aux A,aux B)
{
if(A.r[0]==B.r[0])
return A.r[1]<B.r[1];
else return A.r[0]<B.r[0];
}
bool cmp2(sufix A,sufix B)
{
return A.pozitie<B.pozitie;
}
int lcp(int i,int j)///lcp(i,j) returneaza lungimea celui mai lung prefix al sufixelor ce incep pe pozitiile i si j
{
if(i==j)
return n-i;
int ans=0;
for(int k=lg;k>=0&&i<n&&j<n;k--)
{
if(dp[k][i]==dp[k][j])
i+=(1<<k),j+=(1<<k),ans+=(1<<k);
}
return ans;
}
int main()
{
f>>n>>k;
f>>s;
for(int i=0;i<n;i++)
{
dp[0][i]=s[i]-'0';///oferim o ordine relativa, stiu ca nu e chiar pozitia corecta
}
for(int i=1,cnt=1;(1<<i)<(n<<1);i++,cnt<<=1)
{
for(int j=0;j<n;j++)
{
///aici compunem prefixele sufixelor de lungime 2^k din prefixele de lungime 2^(k-1)
l[j].r[0]=dp[i-1][j];
l[j].r[1]=j+cnt<n?dp[i-1][j+cnt]:-1;///-1 pentru dolar gen daca iese din sir
l[j].poz=j;///daca sortam vectorul avem nevoie de pozitii
}
sort(l,l+n,cmp);
for(int j=0;j<n;j++)
{
dp[i][l[j].poz]=j>0&&l[j].r[0]==l[j-1].r[0]&&l[j].r[1]==l[j-1].r[1]?dp[i][l[j-1].poz]:j;
}
}
for(lg=1;(1<<lg)<n;lg++);
for(int i=0;i<n;i++)
v[i].pozitie=dp[lg][i],v[i].index=i;
sort(v,v+n,cmp2);
for(int i=0;i<n-k+1;i++)
{
int pre=lcp(v[i].index,v[i+k-1].index);
if(pre>ans)
ans=pre;
}
g<<ans;
return 0;
}