用集合写H题
Harder Gcd Problem
https://ac.nowcoder.com/acm/contest/5669/H
题意已经有很多大佬说过了,我用集合整了一个好理解但是慢的写法(毕竟2e5.....)
先求出list[x] 表示 x的最大质数因子是list[x],可以筛一波
然后扔进集合,从大质数因子开始遍历。如果集合x大小是奇数(最大质因子是x的数字有奇数个),那就把其中的偶数扔进集合2.最后把集合2判断完就行(逃
#include<iostream> #include<set> #include<vector> using namespace std; const int Maxn = 2e5 + 11; const int maxn = 2e5 + 11; int prime[Maxn]; int Mark[Maxn + 1]; vector<int>chal; int pr() {//筛素数不用看 int p = 0; Mark[0] = 1; Mark[1] = 1; for (int i = 2; i < Maxn; i++) { if (Mark[i] == 0) { prime[p++] = i; } for (int j = 0; j < p && prime[j] * i < Maxn; j++) { Mark[i * prime[j]] = 1; if (i % prime[j] == 0) { break; } } } return p; } int list[maxn]; set<int>ins[maxn]; set<int>::iterator it; int main() { pr(); for(int i=0; i<maxn; i++) { if(!Mark[i]) list[i] = i;//质数的list就是他自己 } for(int i=2; i<maxn; i++) {//求出list for(int j=2; j*i<maxn; j++) { list[i*j] = max(list[i],max(list[j],list[i*j])); } } int t; scanf("%d",&t); while(t--) { int n; scanf("%d",&n); for(int i=2; i<=n; i++) ins[i].clear(); chal.clear(); for(int i=2; i<=n; i++) { if(i>(n/2) && list[i] == i) continue;//扔掉没用的答案 ins[list[i]].insert(i); } for(int i=n; i>2; i--) { if(ins[i].size() == 0) continue; if(ins[i].size() % 2 == 0) { //全配对 int j = 0; for(it = ins[i].begin(); it != ins[i].end(); it++) { int a = *it; chal.push_back(a); } } else { //扔出去一个偶数 int cns = i*2; it = ins[i].find(cns); ins[i].erase(it); ins[2].insert(cns); int j=0; for(it = ins[i].begin(); it != ins[i].end(); it++) { int a = *it; chal.push_back(a); } } } if(ins[2].size() & 1) { ins[2].erase(ins[2].begin()); } for(it = ins[2].begin(); it != ins[2].end(); it++) { int a = *it; chal.push_back(a); } printf("%d\n",chal.size()/2);//输出答案 for(int i=0;i<chal.size();i+=2){ printf("%d %d\n",chal[i],chal[i+1]); } } return 0; }