Quiz Master - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
![](https://i-blog.csdnimg.cn/blog_migrate/97a0a67d92fcbb0105b32dd95cfd4f3f.png)
选择原序列中的一些数,使得这些数的因子在1~m中都出现过,输出保留的这些数中的最大值和最小值的差
#include <bits/stdc++.h>
#include <iostream>
#include<unordered_map>
#include<unordered_set>
#define x first
#define y second
#define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
using namespace std;
typedef long long LL ;
typedef unsigned long long ULL ;
typedef pair<int,int> PII ;
typedef pair<LL,int> PLI ;
const int N = 1e5+ 10 ;
const LL INF2 = 1e17;
vector<LL> fac[N + 10];// 将每个数的因子放进去
void init()
{
for(int i=1;i<=N;i ++ )
{
for(int j=i;j<=N;j+=i)
{ fac[j].push_back(i); }
}
}
inline void solve()
{
int n,m;
cin >> n>> m;
vector<PII> a;
for(int i=0;i<n;i ++ )
{
int v;cin >> v;
a.push_back(make_pair(v,i));
}
sort(a.begin(),a.end());
vector<int> st(m + 5,0);//判断当前因子是否出现过
int cnt=0,j=0,ans=1e9;
// [j,i]
for(int i=0;i<n; i++ )
{
for(auto x : fac[a[i].x])// 取出当前数的每个因子
{
if(x > m ) break;
if(!st[x] ++ ) cnt ++ ;
}
while(cnt == m )// 当所需的因数满足的时候,尝试移动左端点
{
int t= a[i].x - a[j].x;
if(t < ans ) ans = t;
for(auto x:fac[a[j].x])
{
if(x > m ) break;
if(-- st[x] == 0)
cnt -- ;
}
j ++; // 移动左端点
}
}
cout << (ans >= 1e9?-1 : ans )<<"\n";
}
signed main()
{
ios
init();
int T=1;
cin>>T;
while(T -- )
{
solve();
}
return 0;
}