2020牛客暑期多校训练营(第四场)H.Harder Gcd Problem

2020牛客暑期多校训练营(第四场)H.Harder Gcd Problem

题目链接

题目描述

After solving the Basic Gcd Problem, ZYB gives you a more difficult one:

Given an integer {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 = \emptyset AB=
  • Let A= { a 1 , a 2 , … , a m } \{a_1,a_2,\dots,a_{m}\} {a1,a2,,am} and B = { b 1 , b 2 , … , b m } B=\{b_1,b_2,\dots,b_m\} B={b1,b2,,bm}, there exists two permutations p 1 , p 2 , … , p m p_1,p_2,\dots,p_m p1,p2,,pm and q 1 , q 2 , … , q m q_1,q_2,\dots,q_m q1,q2,,qm such that for each 1 ≤ i ≤ m 1 \le i \le m 1im, gcd ⁡ ( a p i , b q i ) > 1 \gcd(a_{p_i}, b_{q_i}) > 1 gcd(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 ( 4 ≤ n ≤ 2 × 1 0 5 ) {n} (4 \le n \le 2 \times 10^5) n(4n2×105)
It’s guaranteed that the sum of n {n} n of all test cases will not exceed 2 × 1 0 5 2 \times 10^5 2×105.

输出描述:

For each test case, output an integer {m}m in the first line. In the next {m}m lines, each contains two integers a i a_i ai and b i b_i bi ( gcd ⁡ ( a i , b i ) > 1 (\gcd(a_i, b_i) > 1 (gcd(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.

示例1

输入

2
4
10

输出

1
2 4
4
3 9
5 10
8 2
4 6

这题典型的思维题,而且的 cf 原题,吐了
题目链接
我怕自己讲得不好,直接挂官方题解,间接明了:
2020牛客暑期多校训练营(第四场)H.Harder Gcd Problem_第1张图片
AC代码如下:

#include
using namespace std;
typedef long long ll;
const int N=2e5+10;
int prime[N],k,t,n;
bool isprime[N],vis[N];
vector<pair<int,int> >ans;
vector<int>v[N];
void Prime(){
    fill(isprime,isprime+N,1);
    k=0;
    prime[1]=0;
    for(int i=2;i<N;i++){
        if(isprime[i]){
            prime[k++]=i;
            for(ll j=2;i*j<N;j++)
                isprime[i*j]=0;
        }
    }
}

void init(){
    ans.clear();
    for(int i=1;i<=n;i++) vis[i]=0,v[i].clear();
}

int main(){
    Prime();
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        init();
        int pos=upper_bound(prime,prime+k,n/2)-prime;
        for(int i=pos-1;i>=1;i--){
            int p=prime[i];
            for(int j=p;j<=n;j+=p){
                if(!vis[j]){
                    v[p].push_back(j);
                    vis[j]=1;
                }
            }
            if(v[p].size()%2){
                v[2].push_back(p*2);
                v[p].erase(v[p].begin()+1);
            }
            int len=v[p].size()/2;
            for(int i=0;i<len;i++){
                ans.push_back({v[p][i],v[p][i+len]});
            }
        }
        for(int i=2;i<=n;i++) if(!vis[i]&&i%2==0) v[2].push_back(i);
        int len=v[2].size()/2;
        for(int i=0;i<len;i++) ans.push_back({v[2][i],v[2][i+len]});
        printf("%d\n",ans.size());
        for(auto i:ans) printf("%d %d\n",i.first,i.second);
    }
    return 0;
}

你可能感兴趣的:(思维,素筛,牛客)