1366D - Two Divisors
题意:寻找d1 > 1, d2 > 1,使得d1 | ai, d2 | ai且gcd(d1 + d2, ai) = 1;
暴力理解题意:
处理出d | ai,枚举验证(超时显然)
假设我们已经找到了符合题意得d1和d2,则有一下性质:
1.gcd(d1, d2) = 1;
2.\(\forall\) p \(\mid\) ai, 有 p \(\nmid\) (d1 + d2)
若 \(\forall\) p \(\mid\) ai, p \(\mid\) d1 与 p \(\mid\) d2 只能其中一个成立
则有:
- 若 \(\forall\) p \(\mid\) ai 且 p \(\mid\) d1 且 p \(\nmid\) d2, 有 d1 + d2 = d2 (mod p)
- 若 \(\forall\) p \(\mid\) ai 且 p \(\nmid\) d1 且 p \(\mid\) d2, 有 d1 + d2 = d1 (mod p)
所以根据上述分析,我们可以得出最易求解的答案:
将ai所有质因子分成两部分,一部分分给d1, 一部分分给d2;
更进一步:
d1为ai的最小质因子,d2为ai除于d1的幂剩余的存在
到此,题目完美解决:
我们从目标出发,假设我们已经求解出答案,得出答案下的某些重要特性,并依据这些特性不断简化,得到核心特征,即答案符合该核心特征,
然后构造出符合这种核心特征的合理解,证明符合该核心特征的解均符合目标。
简化:从终点出发,得出终点的核心特征,证明终点与核心特征之间是充要关系。然后依据核心特征构造合理解。
点击查看代码
#include<bits/stdc++.h>
using i64 = long long;
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n; std::cin >> n;
std::vector<int> a(n);
for(int i = 0; i < n; ++i){
std::cin >> a[i];
}
std::vector<int> vis(10000001), pf(10000001), p;
for(int i = 2; i <= 10000000; ++i){
if(!vis[i]){
p.push_back(i);
pf[i] = i;
}
for(int j = 0; j < (int)p.size() && i * p[j] <= 10000000; ++j){
vis[i * p[j]] = 1;
pf[i * p[j]] = p[j];
if(i % p[j] == 0){
break;
}
}
}
std::vector<int> ans1(n, -1), ans2(n, -1);
for(int i = 0; i < n; ++i){
int now = a[i];
while(now % pf[a[i]] == 0){
now /= pf[a[i]];
}
if(now != 1){
ans1[i] = pf[a[i]], ans2[i] = now;
}
}
for(auto x : ans1){
std::cout << x << ' ';
} std::cout << '\n';
for(auto x : ans2){
std::cout << x << ' ';
} std::cout << '\n';
return 0;
}
浙公网安备 33010602011771号