题目大意
解题思路
可以发现g小于等于k+1时,只要小于g的数的个数不超过f就是合法的。对于g大于k+1时,统计a在取值范围内有多少个a是g的倍数,可以发现每个a只会贡献一次,开一个桶记录即可,时间复杂度是调和级数nlogn。
code
#pragma GCC optimize(2)
#include
#include
#include
#include
#define LL long long
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define fr(i,j) for(int i=begin[j];i;i=next[i])
#define f2(i,j) for(int i=begi2[j];i;i=nex2[i])
using namespace std;
int const mn=2*1e6+9,inf=1e9+7;
int t,n,k,f,a[mn],b[mn];
int max(int x,int y){
return (x>y)?x:y;
}
int read(){
char ch=getchar();
while((ch<'0')||(ch>'9'))ch=getchar();
int v=0;
while((ch>='0')&&(ch<='9'))v=v*10+ch-'0',ch=getchar();
return v;
}
int c[20];
void write(int v){
c[0]=0;
while(v){
c[++c[0]]=v%10;
v/=10;
}
fd(i,c[0],1)putchar(c[i]+'0');
putchar(' ');
}
int main(){
scanf("%d",&t);
fo(cas,1,t){
scanf("%d%d%d",&n,&k,&f);
int mx=0,mi=inf;
fo(i,1,n){
a[i]=read();
b[max(a[i]-k,1)]++,b[a[i]+1]--;
mx=max(mx,a[i]);
}
sort(a+1,a+n+1);
fo(i,1,mx)b[i]+=b[i-1];
int lim=k+1,tmp;
if(f+1<=n)lim=min(lim,a[f+1]);
fo(i,1,lim)write(i);
int j;
fo(i,k+2,mx){
tmp=0;
for(j=i;j<=mx;j+=i)tmp+=b[j];
if(tmp>=n-f)write(i);
}
fo(i,1,mx)b[i]=0;
printf("\n");
}
return 0;
}