1. 程式人生 > >Codeforces Round #448 (Div. 2)C. Square Subsets

Codeforces Round #448 (Div. 2)C. Square Subsets

cos 什麽 using click clu pla std pri ***

可以用狀壓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; } /******************** ********************/
View Code

Codeforces Round #448 (Div. 2)C. Square Subsets