这道题自己写了个很挫的代码,而且WA on test 39,不知道错在哪里,于是翻看神牛的代码,瞬间被震撼了!
以后素数问题可以这么写!
亮点1:
p[i] : i的一个因子
for ( int j=s[i]; j>1; j/=p[j] ) :这句话一定能找到s[i]的所有因子!
亮点2:
处理最大公约数问题可以“交叉”来,这样照顾到2方面
启示:1.比赛时的空间很充裕!
2.学会巧妙地定义数组,然后不要被从前的思维所束缚!
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100010
#define S 10000010
#define SZ(x) ((int)(x).size())
#define FOR(it,c) for ( __typeof((c).begin()) it=(c).begin(); it!=(c).end(); it++ )
using namespace std;
int p[S];
void predo() { // j一定可以得到一个素因子p[j]
for ( int i=2; i*i<S; i++ ) if ( !p[i] ) for ( int j=i*i; j<S; j+=i ) p[j]=i;
for ( int i=2; i<S; i++ ) if ( !p[i] ) p[i]=i;
}
void shik( int n, int s[], int t[] ) {
for ( int i=0; i<n; i++ )
for ( int j=s[i]; j>1; j/=p[j] ) // 这么写很快又很短!一定能找到所有的因子
t[p[j]]++;
}
void meow( int n, int s[], int t[] ) {
for ( int i=0; i<n; i++ ) {
int x=1;
for ( int j=s[i]; j>1; j/=p[j] ) { // 一定能找到所有因子!
if ( t[p[j]]>0 ) t[p[j]]--;
else x*=p[j];
}
printf("%d%c",x,i==n-1?'\n':' ');
}
}
int n,m,a[N],b[N],x[S],y[S];
int main()
{
predo();
scanf("%d%d",&n,&m);
for ( int i=0; i<n; i++ ) scanf("%d",a+i);
for ( int i=0; i<m; i++ ) scanf("%d",b+i);
printf("%d %d\n",n,m);
shik(n,a,x);
shik(m,b,y);
meow(n,a,y); // 交叉
meow(m,b,x);
return 0;
}