D. Two Divisors
题目描述:
对每个数x,找出它的2个因数a,b使得gcd(a+b,x)==1.否则输出-1。
分析:
每个数x都可以分成若干个质因数乘积的形式。假设x有3个质因数(a,b,c),x=a^i * b^j * c^k。我们先取任意质数如a,剩下质因数合在一起。
下面证明a^i + b^j * c^k与x互质:
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<sstream> #include<vector> #include<stack> #include<deque> #include<cmath> #include<map> #include<queue> #include<bitset> #define sd(x) scanf("%d",&x) #define ms(x,y) memset(x,y,sizeof x) #define fu(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) #define all(a) a.begin(),a.end() using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn=1e7+79; const int mod=1e9+7; const ll INF=1e18+7; int aprm[maxn];//它的其中一个质因数 int a[maxn],b[maxn]; bool isp[maxn]; vector<int> prm; void get_prm() { ms(isp,1); isp[1]=0; fu(i,2,maxn-1) { if(isp[i]) { prm.push_back(i); aprm[i]=i;//i的质因数是i } for(int p:prm) { if(i*p>=maxn) break; isp[i*p]=0; aprm[i*p]=p;//i*p的一个质因数是p if(i%p==0) break; } } } int main() { int n; sd(n); get_prm(); ms(a,-1); ms(b,-1); fu(i,1,n) { int x; sd(x); int p=aprm[x]; int j=x,k=1; while(j%p==0) { j/=p; k*=p; } if(j!=1) { a[i]=j; b[i]=k; } } fu(i,1,n) printf("%d ",a[i]); cout<<endl; fu(i,1,n) printf("%d ",b[i]); cout<<endl; return 0; }