test20260714
\(P4095\)
易
\(P4343\)
易
\(P3518\)
首先如果\(x\) 是密码,那么,所有\(gcd(n,x)\)的倍数的数都是密码
进而,所有密码集合和\(n\)的公约数\(d\) 是所有密码的约数
所以要让密码数量最多,就是让\(d\)尽可能的小
所以要把原问题转换为对\(d\) 的限制
- \(x\) 是密码 : \(d\) 整除 \(gcd(x,n)\)
- \(x\) 不是密码 : \(d\) 不整除 \(gcd(x,n)\)
所以要在这两个限制下,找到最小的\(d\)
代码中先枚举所有 \(n\) 的因数,再判断是否符合限制条件
对于不是密码的限制,是先把所有\(gcd\)标记掉,然后随着枚举\(n\)的因数,在一步一步标记调不合法的更小的\(n\)的因数,然后如果一个因数没有被标记,在判断是密码的限制条件
#include<bits/stdc++.h>
#define int long long
#define fore(i,a,b) for( int i=(a); i<=(b); ++i)
#define repe(i,a,b) for( int i=(a); i>=(b); --i)
using namespace std;
const int N = 2e4 + 10;
int n, k, v, ans;
vector<int> P, p;
map<int, bool> mp;
int gcd(int x,int y) {
if(y == 0) return x;
return gcd(y, x % y);
}
bool cmp(int A,int B) {
return A > B;
}
void dfs(int dep,int v) {
if(dep > P.size()) {
p.push_back(v);
return;
}
dfs(dep + 1, v);
while(v * P[dep - 1] <= n && n % (v * P[dep - 1]) == 0) {
dfs(dep + 1, v * P[dep - 1]);
// cerr << dep << ' ' << v << ' ' << v * P[dep - 1] << '\n';
v *= P[dep - 1];
}
}
void init() {
// cerr << "start init\n";
int x = n;
for(int i = 2; i * i <= x; i ++) {
if(x % i == 0) {
while(x % i == 0) x /= i;
P.push_back(i);
}
}
if(x > 1) P.push_back(x);
// for(int D : P) cout << D << ' ';
// cout << '\n';
// cerr << "start dfs\n";
dfs(1, 1);
// cerr << "dfs ok \n";
sort(p.begin(), p.end(), cmp);
}
signed main(){
ios::sync_with_stdio(false);
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
int in;
cin >> n >> k;
init();
// cerr << "initok\n";
for(int i = 1; i < k; i ++) {
cin >> in;
mp[gcd(in, n)] = 1;
}
cin >> in;
v = gcd(in, n);
for(int d : p) {
if(mp.find(d) != mp.end()) {
for(int D : P) {
if(d % D == 0) mp[d / D] = 1;
}
} else if(v % d == 0) {
ans = max(ans, n / d);
}
}
cout << ans << '\n';
return 0;
}

浙公网安备 33010602011771号