题意:给出n个数字,我们成一个不为空的子序列为好,当其内所有元素乘积为一个完全平方数的时候。问有多少好的子序列。
做法:我发现给出的样例结果很有意思。,都是2的k次方减1。
对于一个数,根据算数基本定理,可以得出,我们把素因子抽象为线代中的秩。于是子序列中的相乘,就等于该维度上的相加。可以得出一个有趣的结论,对于一个子序列,当所有秩上的数之和为一个偶数,那么他就是完全平方数,否则就不是。而奇偶是交替出现的,我们可以用异或来代替,那么做法呼之欲出了,就是线性基。剩下的就是数据范围的考虑,,这个范围里只有19个素数,不会爆longlong(会爆的话我就换种写法),非常契合我们的线性基。
vector<ll>B; void insert(ll x){ for(auto &b:B)x=min(x,b^x); for(auto &b:B)b=min(b,x^b); if(x)B.push_back(x); } void solve(){ int n;cin>>n; vector<int>p; for(int i=1;i<=70;i++){ if(miller_rabbin(i))p.push_back(i); } for(int i=1;i<=n;i++){ int c;cin>>c; ll res=0ll; for(auto j:p){ res<<=1; int cnt=0; while(c%j==0){ c/=j;cnt^=1; } res+=(ll)cnt; } insert(res); } cout<<binpow(2ll,(ll)(n-(ll)B.size()),mod)-1ll;