【构造】[Atcoder Grand Contest 022]B GCD Sequence

题意:

定义一种集合,对集合中的每个数字 a i ,其余数字之和 s u m i ,要求 G C D ( a i , s u m i ) 1
并且,对于每个数字 a 1 , a 2 a n
要求 G C D ( a 1 , a 2 , a 3 , a n ) = 1
现在给出n,求任意一个满足的集合。


分析:

只要在集合中保证有2与3,就必然能满足 G C D ( a 1 , a 2 , a 3 , a n ) = 1
并且,由于 G C D ( a i , s u m i ) = G C D ( a i , a i + s u m i ) ,所以只需要满足 G C D ( a i , s u m ) 1 即可。
只要保证集合的和为6的倍数,那么2的倍数与3的倍数均可以加入,有个特征:每两个相邻的不是6的倍数的偶数,其和必然为6的倍数(2+4=6,8+10=18,……),同样的,每两个相邻的不是6的倍数的3的倍数,其和也为6的倍数(3+9=12,15+21=36,……)

根据这个性质依次插入值即可,对于n=3要特判输出样例(因为初始保证必须有2,3,也就必须有4,9,所以只能做对n 4的数据)。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define SF scanf
#define PF printf
#define MAXN 100010
using namespace std;
int n;
bool used[MAXN];
int main(){
    SF("%d",&n);
    if(n==3){
        PF("2 5 63");
        return 0;
    }
    used[2]=1,used[4]=1,used[3]=1,used[9]=1;
    n-=4;
    int x=8,y=10;
    while(n>1&&y<=30000){
        used[x]=1;
        used[y]=1;
        n-=2;
        x+=6;
        y+=6;
    }
    x=15,y=21;
    while(n>1&&y<=30000){
        used[x]=1;
        used[y]=1;
        n-=2;
        x+=12;
        y+=12;
    }
    x=6;
    while(n>0&&x<=30000){
        used[x]=1;
        x+=6;
        n--;
    }
    for(int i=2;i<=30000;i++)
        if(used[i]==1)
            PF("%d ",i);
} 

猜你喜欢

转载自blog.csdn.net/qq_34454069/article/details/79834509