Codeforces Round #448 (Div. 2)C. Square Subsets
Posted walfy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #448 (Div. 2)C. Square Subsets相关的知识,希望对你有一定的参考价值。
可以用状压dp,也可以用线型基,但是状压dp没看台懂。。。
线型基的重要性质
性质一:最高位1的位置互不相同
性质二:任意一个可以用这些向量组合出的向量x,组合方式唯一
性质三:线性基的任意一个子集异或和不为0.
详细见:线型基介绍
题意:给一个数组,找相乘起来是完全平方数的所有组数
解法:先打70的素数表,对每一个数的素数因子个数%2之后进行压位,为什么要这样做呢,是因为,相乘之后如果是素数那么一定能分解成偶数个素数因子相乘,那么就可以转化成求亦或起来是0的组数,用线型基处理,对于不在线型基中的元素,那么它亦或线型基中某些数一定能变成0,那么就是找线型基的个数然后枚举所有可能的情况,就是2^t(t是不在线型基中的元素个数),最后排除一个也不取的情况
#include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define C 0.5772156649 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define pii pair<int,int> using namespace std; const double g=10.0,eps=1e-12; const int N=100000+10,maxn=200000+10,inf=0x3f3f3f3f; bool isprime[75]; int prime[75],cnt; void getprime() { cnt=0; for(int i=2;i<=70;i++) { if(!isprime[i]) { prime[cnt++]=i; for(int j=2*i;j<=70;j+=i) isprime[j]=1; } } } int main() { getprime(); int n; scanf("%d",&n); vector<int>base; int k=0; for(int i=1;i<=n;i++) { int x; scanf("%d",&x); int te=0; for(int j=0;j<cnt;j++) { while(x%prime[j]==0) { x/=prime[j]; te^=(1<<j); } } for(int j=0;j<base.size();j++) te=min(te,te^base[j]); if(te)base.pb(te); else k++; } ll ans=1; for(int i=0;i<k;i++) ans=ans*2%mod; printf("%lld\\n",(ans-1+mod)%mod); return 0; } /******************** ********************/
以上是关于Codeforces Round #448 (Div. 2)C. Square Subsets的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #256 (Div. 2/A)/Codeforces448A_Rewards(水题)
Codeforces Round #448 (Div. 2) B
CF Codeforces Round #256 (Div. 2) D (448D) Multiplication Table