Longest Repeated subsequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 951 Accepted Submission(s): 188
Problem Description
Write a program that takes a sequence of number and returns length of the longest repeated
subsequence. A repeated subsequence which repeats identically at least K times without overlaps.
For example 1 2 3 1 2 3 2 3 1 repeats 2 3 for three times.
subsequence. A repeated subsequence which repeats identically at least K times without overlaps.
For example 1 2 3 1 2 3 2 3 1 repeats 2 3 for three times.
Input
Line 1: The input contains a single integer T , the number of test cases.
Line 2: Two space-separated integers: N and K (1 <= n <= 50000), (2 <= k <= n)
Lines 3..N+2: N integers, one per line. The integer is between 0 and 10^9.
It is guaranteed that at least one subsequence is repeated at least K times.
Line 2: Two space-separated integers: N and K (1 <= n <= 50000), (2 <= k <= n)
Lines 3..N+2: N integers, one per line. The integer is between 0 and 10^9.
It is guaranteed that at least one subsequence is repeated at least K times.
Output
For each test case, the first line print the length n of the Longest Repeated Subsequence and the line 2…n+1 print the subsequence numbers.(if we have several subsequence with the same length output the lexicographic order smallest one). Separate output for
adjacent cases with a single blank line.
Sample Input
1 8 2 1 2 3 2 3 2 3 1
Sample Output
2 2 3
题意:给一个含n个数的序列,求最少重复k次的最长子序列(子序列不能重叠)。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <map>
using namespace std;
const int N=200010;
const int INF=0x7FFFFFFF;
struct Sa
{
int s[N],a[N],b[N];
int rk[2][N],sa[N],h[N],w[N],now,k,m,n;
int rmq[N][20],lg[N],bel[N];
bool GetS()
{
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]),s[i]=a[i];
sort(a+1,a+1+n);
m=unique(a+1,a+1+n)-a;
for(int i=1;i<=n;i++)
s[i]=lower_bound(a+1,a+m,s[i])-a;
return true;
}
void getsa(int z,int &m)
{
int x=now,y=now^=1;
for(int i=1; i<=z; i++) rk[y][i]=n-i+1;
for(int i=1,j=z; i<=n; i++)
if(sa[i]>z) rk[y][++j]=sa[i]-z;
for(int i=1; i<=m; i++) w[i]=0;
for(int i=1; i<=n; i++) w[rk[x][rk[y][i]]]++;
for(int i=1; i<=m; i++) w[i]+=w[i-1];
for(int i=n; i>=1; i--) sa[w[rk[x][rk[y][i]]]--]=rk[y][i];
for(int i=m=1; i<=n; i++)
{
int *a=rk[x]+sa[i],*b=rk[x]+sa[i-1];
rk[y][sa[i]]=*a==*b&&*(a+z)==*(b+z)?m-1:m++;
}
}
void getsa(int m)
{
now=rk[1][0]=sa[0]=s[0]=0;
for(int i=1; i<=m; i++) w[i]=0;
for(int i=1; i<=n; i++) w[s[i]]++;
for(int i=1; i<=m; i++) rk[1][i]=rk[1][i-1]+(bool)w[i];
for(int i=1; i<=m; i++) w[i]+=w[i-1];
for(int i=1; i<=n; i++) rk[0][i]=rk[1][s[i]];
for(int i=1; i<=n; i++) sa[w[s[i]]--]=i;
rk[1][n+1]=rk[0][n+1]=0;
for(int x=1,y=rk[1][m]; x<=n&&y<=n; x<<=1) getsa(x,y);
for(int i=1,j=0; i<=n; h[rk[now][i++]]=j?j--:j)
{
if(rk[now][i]==1) continue;
int k=n-max(sa[rk[now][i]-1],i);
while(j<=k&&s[sa[rk[now][i]-1]+j]==s[i+j]) ++j;
}
}
void getrmq()
{
h[n+1]=h[1]=lg[1]=0;
for(int i=2; i<=n; i++)
rmq[i][0]=h[i],lg[i]=lg[i>>1]+1;
for(int i=1; (1<<i)<=n; i++)
{
for(int j=2; j<=n; j++)
{
if(j+(1<<i)>n+1) break;
rmq[j][i]=min(rmq[j][i-1],rmq[j+(1<<i-1)][i-1]);
}
}
}
int lcp(int x,int y)
{
int l=min(rk[now][x],rk[now][y])+1,r=max(rk[now][x],rk[now][y]);
return min(rmq[l][lg[r-l+1]],rmq[r-(1<<lg[r-l+1])+1][lg[r-l+1]]);
}
int check(int x,int &y)
{
int sum=0;
b[sum++]=sa[1];
for(int i=2;i<=n+1;i++)
{
if(i<=n&&h[i]>=x) b[sum++]=sa[i];
else
{
sort(b,b+sum);
int t=b[0],cnt=1;
for(int j=1;j<sum;j++)
if(b[j]>=x+t) t=b[j],cnt++;
if(cnt>=k) {y=sa[i-1];return true;}
sum=0;b[sum++]=sa[i];
}
}
return false;
}
void work()
{
getsa(m);
int l=1,r=n,g;
while(l<=r)
{
if(check(l+r>>1,g)) l=(l+r>>1)+1;
else r=(l+r>>1)-1;
}
check(r,g);
printf("%d\n",r);
for(int i=1;i<=r;i++)
printf("%d\n",a[s[g+i-1]]);
}
}sa;
int main()
{
int t,cas=0;
scanf("%d",&t);
while(t--)
{
if(cas) printf("\n");
cas=1;
sa.GetS();
sa.work();
}
return 0;
}