请教了比利
首先
2n
次项是没有问题的,比如
2√+3√
,可以构造
f(x)=(x+2√+3√)(x+2√−3√)(x−2√+3√)(x−2√−3√)
这个不是最优解
最优解应该是构造这样一个矩阵 每一行代表一个质因子 每一列代表根式中的一项 有奇数次这个质因子的一项 那一列为
1
否则为
然后这个矩阵的线性基的大小
m
就是最优答案
我还没有想明白 然而退役了 也就以后再深究吧
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<bitset>
#include<cassert>
using namespace std;
typedef long long ll;
#define read(x) scanf("%d",&(x))
const int maxn=200005;
const int P=1e9+7;
int vst[maxn];
int prime[maxn],num;
inline void Pre(int n){
for (int i=2;i<=n;i++){
if (!vst[i]) prime[++num]=i;
for (int j=1;j<=num && (ll)i*prime[j]<=n;j++){
vst[i*prime[j]]=1;
if (i%prime[j]==0) break;
}
}
}
const int N=505;
bitset<N> B[20005];
int n,a[N];
int sx[20000],icnt;
inline int Bin(int x){
return lower_bound(sx+1,sx+icnt+1,x)-sx;
}
int main(){
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
Pre(2e5);
read(n);
for (int i=1;i<=n;i++){
read(a[i]); int t=a[i];
for (int j=1;j<=num && (ll)prime[j]*prime[j]<=a[i];j++)
if (t%prime[j]==0){
sx[++icnt]=prime[j];
while (t%prime[j]==0) t/=prime[j];
}
if (t>1) sx[++icnt]=t;
}
sort(sx+1,sx+icnt+1); icnt=unique(sx+1,sx+icnt+1)-sx-1;
for (int i=1;i<=n;i++){
int t=a[i];
for (int j=1;j<=num && (ll)prime[j]*prime[j]<=a[i];j++)
if (t%prime[j]==0){
int it=Bin(prime[j]); int c=0;
while (t%prime[j]==0)
c^=1,t/=prime[j];
B[it][i]=c;
}
if (t>1){
B[Bin(t)][i]=1;
}
}
ll ans=1; int k=0;
for (int i=1;i<=n;i++){
int t=0;
for (int j=k+1;j<=icnt;j++) if (B[j][i]) t=j;
if (t){
swap(B[++k],B[t]);
(ans<<=1)%=P;
for (int j=k+1;j<=icnt;j++)
if (B[j][i])
B[j]^=B[k];
}
}
assert(k<=n);
printf("%d\n",ans);
return 0;
}