在b中选出n个数ai,这个子序列是好的当且仅当能找到满足如下条件的x:
2a1(2∗x1+a1−1)+2a2(2∗x2+a2−1)+...+2an(2∗xn+an−1)=0,{xi∣xi∈Z}
(2∗x1−1)∗a1+(2∗x2−1)∗a2+...+(2∗xn−1)∗an=−a12−a22−...−an2,{xi∣xi∈Z}
x1∗a1+x2∗a2+...+xn∗an=−a12−a22−...−an2,{xi∣xi%2==1}
(x1+a1)∗a1+(x2+a2)∗a2+...+(xn+an)∗an=0,{xi∣xi%2==1}
x1∗a1+x2∗a2+...+xn∗an=0,{xi∣ai为奇数则xi为偶数,反之xi为奇数}
- 如果存在多个ai为奇数,那么我们取一个奇数的ak,其它的奇数ai对应的xi制为0,对每个偶数aj,我们一定能解得xj、xkj(xj<0,xkj>0)使得xj∗aj+xkj∗ak=0,将所有的xkj求和得到xk使得等式成立。
- 假设这个n个数都是偶数,不断提取公因子2,最后为常数为奇数的项有res个。如果res为奇数,将这些项合并成一个项后就是一个奇数,而其它项都是偶数,那么所有项之和一定不为0;反之可以任取res中的两项去抵消其它项。
第2点的例子:
a_1=5 a_2=9 a_3=2*3
x_1=3*9 x_2=3*5 x_3=-5*9
a_1=5 a_2=9 a_3=2*2*7
x_1=3*7*9 x_2=5*7 x_3=-5*9
a_1=5 a_2=9 a_3=2*3 a_4=2*2*7
x_1=3*9+3*7*9 x_2=3*5+5*7 x_3=-5*9 x_4=-5*9
对每个数按因子2的个数i分类,因子2的个数为i的数有cnt个,因子2的个数大于i的数有sum个,i从30到i枚举,因子2的个数为i的数选出偶数个,选法有22cnt−1(选出奇数个的方案数=选出偶数个的方案数,选出偶数个的方案包含了空集),然后因子2的个数大于i的每个数可选可不选,选法有种2sum,总的贡献为(2cnt−1−1)∗2sum。因子2的个数为1的数是奇数,每个数可选可不选(空集除外),总的贡献为(2cnt−1)∗2sum
code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn=2e5+7,mod=1e9+7;
ll qpow(ll a, ll b) {
ll ans = 1;
while (b) {
if (b & 1)
ans = ans * a % mod;
a = a * a % mod;
b >>= 1;
}
return ans;
}
inline void solve() {
int n;
cin>>n;
vector<int>b(32);
for(int i=1,x; i<=n; ++i) {
cin>>x;
int cnt(0);
while(x%2==0) {
x/=2;
++cnt;
}
++b[cnt];
}
ll ans(0);
int cc(0);
for(int i=30; ~i; --i) if(b[i]) {
if(i) ans+=qpow(2,cc)*(qpow(2,b[i]-1)-1)%mod;
else ans+=qpow(2,cc)*(qpow(2,b[i])-1)%mod;
if(ans>=mod) ans-=mod;
cc+=b[i];
}
cout<<ans<<'\n';
}
int main() {
cin.sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
int _=1;
// cin>>_;
while(_--) solve();
return 0;
}