Codeforces 1610D. Not Quite Lee
题目大意
思路
设选出的子序列中第 \(i\) 个数字为 \(b_i\) , 第起始的数字为 \(x_i\) ,于是若该子序列是好的,则 \(\sum_{i=1}^{n}\frac{(2x_i+b_i-1)b_i}{2}=0\) ,即 \(\sum_{i=1}^n b_ix_i=-\sum_{i=1}^n\frac{b_i(b_i-1)}{2}\) ,对于一个给定的子序列,等式右侧是一个定值,根据裴蜀定理,如果有解,那么有 \(gcd(b_1,...,b_n)|\sum_{i=1}^n\frac{b_i(b_i-1)}{2}\) ,即
\(2|\sum_{i=1}^n\frac{b_i(b_i-1)}{gcd(b_1,...,b_n)}\) ,设 \(gcd(b_1,...,b_n)=2^t,2\nmid k\) , \(c_i=\frac{b_i}{2^t}\) , 于是
\(2|\sum_{i=1}^n\frac{c_i2^t(c_i2^t-1)}{2^tk}\to2|\sum_{i=1}^n\frac{c_i(c_i2^t-1)}{k}\to2|\sum_{i=1}^nc_i(c_i2^t-1)\) ,于是我们得到了一个子序列是好的需要满足的条件,接下来我们可以枚举 \(t\) 来计算,记 \(2^t|a\) 并且 \(2^{t+1}\nmid a\) 的数量为 \(cnt_t\) ,当 \(t=0\) 时,显然直接可以满足条件,此时的子序列数为 \((2^{cnt_0}-1)2^{m-cnt_0}\) ,对于其他的 \(t\) ,条件变为 \(2|\sum_{i=1}^nc_i\) ,必须要使得子序列中有偶数个可以正好被 \(2^t\) 整除的数字,并且至少有 \(1\) 个,于是此时好的子序列数量为 \((2^{cnt_t-1}-1)2^{m-\sum_{i=1}^tcnt_i}\) ,最后求和即为答案。
代码
#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
using LL = long long;
using ULL = unsigned long long;
using PII = pair<int, int>;
using TP = tuple<int, int, int>;
#define all(x) x.begin(),x.end()
//#define int LL
//#define lc p*2
//#define rc p*2+1
#define endl '\n'
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
//#pragma warning(disable : 4996)
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
const double eps = 1e-8;
const LL MOD = 1000000007;
const LL mod = 998244353;
const int maxn = 200010;
LL N, A[maxn], t[35];
LL calc(LL x)
{
LL cnt2 = 0;
while (x % 2 == 0)
{
cnt2++;
x /= 2;
}
return cnt2;
}
LL qpow(LL a, LL x)
{
LL ans = 1;
while (x > 0)
{
if (x & 1)
ans = ans * a % MOD;
a = a * a % MOD;
x >>= 1;
}
return ans;
}
void solve()
{
LL ans = 0, tmp = t[0];
ans = (ans + (qpow(2LL, t[0]) - 1 + MOD) % MOD * qpow(2LL, N - tmp) % MOD) % MOD;
for (int i = 1; i <= 29; i++)
{
tmp += t[i];
if (t[i] >= 2)
ans = (ans + (qpow(2LL, t[i] - 1) - 1 + MOD) % MOD * qpow(2LL, N - tmp) % MOD) % MOD;
}
cout << ans << endl;
}
int main()
{
IOS;
cin >> N;
for (int i = 1; i <= N; i++)
cin >> A[i], t[calc(A[i])]++;
solve();
return 0;
}