Codeforces Round#448 C
Posted amitherblogs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round#448 C相关的知识,希望对你有一定的参考价值。
题意:n个数,问多少个集合的乘积是完全平方数 (x<70)
题解:
完全平方数的因子一定出现偶数个,那么问题就变成有多少个集合的异或和为0
就转化成用线性基来写
第i位为1就说明分解质因数后第i个质数出现了奇数次,为0即出现偶数次,之后再把它转回十进制的另一个数
这样问题就变成了n个数,有多少个集合满足它们异或为0
设线性基的维数是m,那么从非基的n−m个数中取任意和做异或得到的数字,均可以通过线性基表出,故答案为2^(n−m)−1,减一同样是去掉取空集的方案
#include <bits/stdc++.h> using namespace std; int n,m,x; const int p=1e9+7; struct L_B{ long long d[61]; L_B(){memset(d,0,sizeof(d));} bool insert(long long val){ for (int i=60;i>=0;i--) if (val&(1LL<<i)){ if (!d[i]){ d[i]=val; break; } val^=d[i]; } return val>0; } }; vector<int> Pr; bool isprime(int x){ for(int i=2;i<x;i++) if(x%i==0) return false; return true; }
//第i位为1就说明分解质因数后第i个质数出现了奇数次,为0即出现偶数次,之后再把它转回十进制的另一个数 int getst(int x){ int st=0; for(int i=0;i<Pr.size();i++) while(x%Pr[i]==0){
st^=(1<<i),x/=Pr[i];
} return st; } int main(){ for(int i=2;i<=70;i++)if(isprime(i)) Pr.push_back(i); scanf("%d",&n); L_B B; int cnt=0; long long ans=1; for(int i=0;i<n;i++){ scanf("%d",&x); if(!B.insert(getst(x))) //如果插入不成功
ans=(ans*2)%p; } printf("%lld ",(ans-1+p)%p); return 0; }
以上是关于Codeforces Round#448 C的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces 448C Painting Fence:分治
Codeforces Round #437 (Div. 2, based on MemSQL Start[c]UP 3.0 - Round 2) E. Buy Low Sell High(代码片
CF Codeforces Round #256 (Div. 2) D (448D) Multiplication Table
Codeforces Round #448 (Div. 2) B. XK Segments进制思维/排序