#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn=50050;
char str[maxn];
int s[maxn];
int sa[maxn]; ///(你排第几)下标:排名情况, 数组值:首字符序号
int rank1[maxn];/// (排第几的是谁) 下标:首字符序号, 数组值:排名情况
int height[maxn]; /// height[i]表示后缀i和后缀i-1的最长公共前缀
int wa[maxn], wb[maxn], wv[maxn], wd[maxn];
int x[maxn], q[maxn];
int pos;
int cmp(int *r, int a, int b, int l)
{
return r[a]==r[b]&&r[a+l]==r[b+l];
}
void da(int *r, int n, int m){ /// 倍增算法 r为待匹配数组 n为总长度 m为字符范围
int i, j, p, *x = wa, *y = wb, *t;
for(i = 0; i < m; i ++) wd[i] = 0;
for(i = 0; i < n; i ++) wd[x[i]=r[i]] ++;
for(i = 1; i < m; i ++) wd[i] += wd[i-1];
for(i = n-1; i >= 0; i --) sa[-- wd[x[i]]] = i;
for(j = 1, p = 1; p < n; j *= 2, m = p){
for(p = 0, i = n-j; i < n; i ++) y[p ++] = i;
for(i = 0; i < n; i ++) if(sa[i] >= j) y[p ++] = sa[i] - j;
for(i = 0; i < n; i ++) wv[i] = x[y[i]];
for(i = 0; i < m; i ++) wd[i] = 0;
for(i = 0; i < n; i ++) wd[wv[i]] ++;
for(i = 1; i < m; i ++) wd[i] += wd[i-1];
for(i = n-1; i >= 0; i --) sa[-- wd[wv[i]]] = y[i];
for(t = x, x = y, y = t, p = 1, x[sa[0]] = 0, i = 1; i < n; i ++){
x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p - 1: p ++;
}
}
}
void calHeight(int *r, int n){ /// 求height数组。
int i, j, k = 0;
for(i = 1; i <= n; i ++) rank1[sa[i]] = i;
for(i = 0; i < n; height[rank1[i ++]] = k){
for(k ? k -- : 0, j = sa[rank1[i]-1]; r[i+k] == r[j+k]; k ++);
}
}
int find(int tmp, int n)
{
int l=0, r=n, mid;
while(l<=r)
{
mid=(l+r)>>1;
if(x[mid]==tmp) return mid;
else if(x[mid]<tmp) l=mid+1;
else r=mid-1;
}
}
int flag;
int judge(int mid,int rear,int k)
{
int cnt=1,i;
std::sort(q,q+rear);
int pre=q[0];
for(i=1;i<rear;i++)
{
if(q[i]-pre>=mid)
{
cnt++;
pre=q[i];
}
}
return cnt>=k;
}
int check(int mid,int n,int k)
{
int i,rear=0;
for(i=1;i<=n;i++)
{
if(height[i]<mid)
{
if(judge(mid,rear,k))
{
flag=sa[i-1];
return 1;
}
q[0]=sa[i];
rear=1;
}
else
q[rear++]=sa[i];
}
if(judge(mid,rear,k))
{
flag=sa[i-1];
return 1;
}
return 0;
}
int main()
{
int cas;
scanf("%d",&cas);
while(cas--)
{
int n,k;
scanf("%d%d",&n,&k);
int i;
for(i=0;i<n;i++)
{
scanf("%d",&x[i]);
s[i]=x[i];
}
std::sort(x,x+n);
int ep=0;
for(i=1;i<n;i++)
{
if(x[i]!=x[ep])
x[++ep]=x[i];
}
for(i=0;i<n;i++)
s[i]=find(s[i],ep)+2;
s[n]=0;
da(s,n+1,n+4);
calHeight(s,n);
int l=1,r=n,mid,ans;
while(l<=r)
{
mid=(l+r)>>1;
if(check(mid,n,k))
{
l=mid+1;
ans=mid;
}
else
{
r=mid-1;
}
}
printf("%d\n",ans);
for(i=flag;i<flag+ans;i++)
{
printf("%d\n",x[s[i]-2]);
}
if(cas)
printf("\n");
}
}
tjut 2890
最新推荐文章于 2019-01-27 21:10:00 发布