http://codeforces.com/problemset/problem/894/C
题意:有数列a[1],a[2],...,a[n],按照方法gcd(a[i],a[i+1],...a[j]) (i<=j),求出所有gcd放入set。现在反过来已知set,求其中一组可能的数列。
题解:比赛时的想法是,①求出所有数的gcd为GCD,一定要等于最小那个数 ,②这个set就是其中的一组解(满足单点gcd)。后来被hack了,数据是1 3 8 12。8和12产生了新的区间gcd。所以应该加入限制,set中每个数需要存在,保证单点gcd。然后每个数前加一个GCD,这样就保证了区间gcd,限制了新的区间gcd的产生。
代码:
#include<bits/stdc++.h>
#define debug cout<<"aaa"<<endl
#define d(a) cout<<a<<endl
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define LL long long
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define MIN_INT (-2147483647-1)
#define MAX_INT 2147483647
#define MAX_LL 9223372036854775807i64
#define MIN_LL (-9223372036854775807i64-1)
using namespace std;
const int N = 100000 + 5;
const int M = N * N + 5;
const int mod = 1000000000 + 7;
const int INF = 0x3f3f3f3f;
const double eps = 1e-8;
int a[N];
int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
int main(){
int n,GCD;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
if(i==1){
GCD=a[i];
continue;
}
GCD=gcd(GCD,a[i]);
}
if(GCD!=a[1]){
puts("-1");
return 0;
}
printf("%d\n",2*n);
for(int i=1;i<=n;i++){
cout<<GCD<<" "<<a[i]<<" ";
}
return 0;
}