时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
Special Judge, 64bit IO Format: %lld
After solving the Basic Gcd Problem, ZYB gives you a more difficult one:
Given an integer n{n}n, find two subset A{A}A and B{B}B of {1,2,…,n}{1,2,\dots,n}{1,2,…,n} such that:
∣A∣=∣B∣=m{|A|=|B|=m}∣A∣=∣B∣=m and A∩B=∅A \cap B = \emptysetA∩B=∅
Let A={a1,a2,…,am}A={a_1,a_2,\dots,a_{m}}A={a1,a2,…,am} and B={b1,b2,…,bm}B={b_1,b_2,\dots,b_m}B={b1,b2,…,bm}, there exists two permutations p1,p2,…,pmp_1,p_2,\dots,p_mp1,p2,…,pm and q1,q2,…,qmq_1,q_2,\dots,q_mq1,q2,…,qm such that for each 1≤i≤m1 \le i \le m1≤i≤m, gcd(api,bqi)>1\gcd(a_{p_i}, b_{q_i}) > 1gcd(api,bqi)>1.
Please find two subsets with maximum value of m{m}m.
There are multiple test cases. The first line of input contains an integer T{T}T, indicating the number of test cases.
For each test case, there is only one line containing an integer n{n}n (4≤n≤2×1054 \le n \le 2 \times 10^54≤n≤2×105)
It’s guaranteed that the sum of n{n}n of all test cases will not exceed 2×1052 \times 10^52×105.
For each test case, output an integer m{m}m in the first line. In the next m{m}m lines, each contains two integers aia_iai and bib_ibi (gcd(ai,bi)>1\gcd(a_i, b_i) > 1gcd(ai,bi)>1), denoting the i{i}i-th element in subset A{A}A and B{B}B.
If there are multiple solutions, you can output any of them.
输入
复制
2
4
10
输出
复制
1
2 4
4
3 9
5 10
8 2
4 6
#include
using namespace std;
typedef long long ll;
const int N=1e6+500;
int f[N],vis[N],yz[N];
vector<int>q[N];
bool cmp(int x,int y) {
if(yz[x]==yz[y])return f[x]>f[y];
return yz[x]<yz[y];
}
int main() {
int T;
scanf("%d",&T);
while(T--) {
int n;
scanf("%d",&n);
for(int i=1; i<=n; ++i) {
f[i]=0;
vis[i]=0;
yz[i]=0;
q[i].clear();
}
for(int i=2; i<=n; ++i) {
if(!f[i]) {
for(int j=i; j<=n; j+=i) {
if(!f[j])f[j]=i;
yz[j]++;
q[i].push_back(j);
}
}
}
int ans=0;
vector<int>ans1;
vector<int>ans2;
for(int i=n/2; i>=2; --i) {
sort(q[i].begin(),q[i].end(),cmp);
int cut1=0,cut2=0;
for(int j=0; j<q[i].size(); ++j) {
if(!vis[q[i][j]]) {
if(!cut1) {
cut1=q[i][j];
} else if(!cut2) {
cut2=q[i][j];
}
}
if(cut1&&cut2) {
ans++;
ans1.push_back(cut1);
ans2.push_back(cut2);
vis[cut1]++;
vis[cut2]++;
cut1=0;
cut2=0;
}
}
}
printf("%d\n",ans);
for(int i=0; i<ans; ++i) {
printf("%d %d\n",ans1[i],ans2[i]);
}
}
return 0;
}