Codeforces Global Round 17 - D. Not Quite Lee
裴蜀定理 + lowbit
题意
定义一个包含 \(m\) 个元素的数组 \(b\) 是好的,当且仅当满足以下两个条件
- 对于 \(b[i]\), 存在一个长度为 \(b[i]\) 的连续的段(如 \(b[i]=4\), [1,2,3,4], [-1,0,1,2]等就是符合条件的)
- 对于这 \(m\) 个段,\(sum_i\) 记为这一段的数字和,并满足 \(\sum sum_i=0\)]
给定一个长度为 \(n\;(1<=n<=2*10^5)\) 的数组 \(a[i]\),求 \(a\) 的 \(2^n-1\) 个非空子序列组成的数组中,有多少个是好的
思路
对于 \(a[i]\) 而言,设选取的一段的第一个数是 \(x_i\), 则 \(sum_i=a_i*x_i+\frac {a_i*(a_i-1)}2\)
若选了 \(a\) 数组的 \(k\) 个数,记为 \(c_1,c_2...c_k\)
\(\sum sum_i=0\Lrarr \sum c_i*x_i=\sum \frac {c_i*(c_i-1)}2\)
根据裴蜀定理,设 \(g=\gcd(c_1,c_2,...,c_k)\), 则要满足 \(g\mid \sum \frac {c_i*(c_i-1)}2\)
如果 \(c_i\) 中存在奇数,则 \(g\) 也一定是奇数,所以右边的除以2不影响整除的性质,又因为 \(g\mid c_i\), 因此 \(g\mid \sum \frac {c_i*(c_i-1)}2\) 恒成立
所以奇数部分对方案数的贡献就是 \(2^{odd}\) (也可以感性考虑,如果存在一个奇数,那么它和其余所有的偶数共有奇数个数,把它们按关于 0 对称排列即可;其余的奇数也关于 0 对称排列)
现在只关心偶数部分,因为 \(g\mid c_i\), 问题是右边的除以 2 之后还能否满足 \(g\mid \sum \frac {c_i*(c_i-1)}2\),(即关心的是 \(c_i\) 的含 2 量) 由于 \(c_i-1\) 为奇数,对除以 2 而言没有意义,不用考虑;
现在转化为 \(g\mid \sum \frac {c_i}2\) 是否成立,记 \(lowb[x]\) 为能整除 \(x\) 的最高的 2 的幂次,例如 \(lowb[8]=3,lowb[16]=4\)
\(lowb[g]<=lowb[c_i]\)
- \(lowb[c_i]>lowb[g]\), 那么 \(\frac {c_i}2\) 仍能被 \(g\) 整除
- \(lowb[c_i]==lowb[g]\), 需要偶数个相等的 \(c_i\) 才能使 \(g\mid \sum \frac {c_i}2\) (需要用到 \(\binom n0+\binom n2+\binom n4+...=2^{n-1}\) 来优化)
代码
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5 + 10;
const int mod = 1e9 + 7;
int n;
int a[N];
int lowb[40];
ll mi[N];
void add(ll &a, ll b)
{
a += b;
if (a >= mod)
a -= mod;
}
void presolve()
{
mi[0] = 1;
for (int i = 1; i <= n; i++)
mi[i] = mi[i-1] * 2 % mod;
for (int i = 1; i <= n; i++)
{
int x = a[i], cnt = 0;
while(x % 2 == 0)
{
x /= 2;
cnt++;
}
lowb[cnt]++;
}
}
ll solve()
{
ll ans = 0;
int even = 0;
for (int i = 1; i <= n; i++)
if (a[i] % 2 == 0) even++;
//至少一个奇数 + 任意个偶数
add(ans, mi[even] * (mi[n - even] - 1 + mod) % mod);
//只有偶数
for (int i = 1; i <= 30; i++)
{
if (!lowb[i])
continue;
even -= lowb[i];
//枚举拿的最小的lowbit,且要拿偶数个,C(n,0) + C(n,2) + C(n,4) + ... == 2^(n-1),且不能拿0个
add(ans, mi[even] * (mi[lowb[i] - 1] - 1 + mod) % mod);
}
return ans;
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
presolve();
cout << solve() << endl;
return 0;
}
Codeforces Global Round 17 - D. Not Quite Lee的更多相关文章
- CodeForces Global Round 1
CodeForces Global Round 1 CF新的比赛呢(虽然没啥区别)!这种报名的人多的比赛涨分是真的快.... 所以就写下题解吧. A. Parity 太简单了,随便模拟一下就完了. B ...
- Codeforces Global Round 1 - D. Jongmah(动态规划)
Problem Codeforces Global Round 1 - D. Jongmah Time Limit: 3000 mSec Problem Description Input Out ...
- Codeforces Global Round 2 题解
Codeforces Global Round 2 题目链接:https://codeforces.com/contest/1119 A. Ilya and a Colorful Walk 题意: 给 ...
- Codeforces Global Round 1 (A-E题解)
Codeforces Global Round 1 题目链接:https://codeforces.com/contest/1110 A. Parity 题意: 给出{ak},b,k,判断a1*b^( ...
- Codeforces Beta Round #17 D. Notepad (数论 + 广义欧拉定理降幂)
Codeforces Beta Round #17 题目链接:点击我打开题目链接 大概题意: 给你 \(b\),\(n\),\(c\). 让你求:\((b)^{n-1}*(b-1)\%c\). \(2 ...
- Codeforces Global Round 3
Codeforces Global Round 3 A. Another One Bites The Dust 有若干个a,有若干个b,有若干个ab.你现在要把这些串拼成一个串,使得任意两个相邻的位置 ...
- Codeforces Global Round 1 (CF1110) (未完结,只有 A-F)
Codeforces Global Round 1 (CF1110) 继续补题.因为看见同学打了这场,而且涨分还不错,所以觉得这套题目可能会比较有意思. 因为下午要开学了,所以恐怕暂时不能把这套题目补 ...
- 【手抖康复训练1 】Codeforces Global Round 6
[手抖康复训练1 ]Codeforces Global Round 6 总结:不想复习随意打的一场,比赛开始就是熟悉的N分钟进不去时间,2333,太久没写题的后果就是:A 题手抖过不了样例 B题秒出思 ...
- Codeforces Global Round 11 个人题解(B题)
Codeforces Global Round 11 1427A. Avoiding Zero 题目链接:click here 待补 1427B. Chess Cheater 题目链接:click h ...
- Codeforces Beta Round #17 C. Balance DP
C. Balance 题目链接 http://codeforces.com/contest/17/problem/C 题面 Nick likes strings very much, he likes ...
随机推荐
- CF生化全模式全装备单机版安装教程(基于CSOL)
喜欢玩CF单机版的朋友平时应该接触过一些基于CS1.6的单机版,但是这种版本有些特性就是:改了分辨率就容易进不去游戏:变为幽灵时被枪射击时会出现视角乱晃的情况:游戏过程中场景宏大变数多时容易突然退出回 ...
- 新的学习历程-python4 input
1 num = input("请输入数字:") # input用于录入键盘输入 2 print(num) 3 print(type(num)) #input获取到数据类型是字符类型 ...
- 如何将PDF文件中的部分信息隐藏或遮盖呢?
由于工作需要,总是需要对PDF文件中的内容进行部分隐藏.之前,作为VIP,可以使用某软件对PDF中的信息进行部分遮盖,现在,VIP到期了,我也不想继续花钱了(哭穷,嘻嘻) 在信息时代,只要会百 ...
- 创建一个与a.txt文件同目录下的另一个文件b.txt
File file1 = new("d:\\a\\a.txt"); File file2 = new(file1.getParent(),"b.txt"): F ...
- 【转】wamp如何添加多个站点
1.打开wamp目录下的bin目录下的apache/conf/extra/httpd-vhosts.conf文件(虚拟目录配置文件),修改文件:在num01下创建index.php文件,输出01,:在 ...
- git+jenkins+ansible+gitlab部署网站
- Windows 与Docker
https://docs.microsoft.com/zh-cn/windows/wsl/install-manual#step-4---download-the-linux-kernel-updat ...
- lua如何转化为exe
在这里下载 https://wwn.lanzout.com/iIS9d07rpesh 然后用cmd到 下载的盘:\luapack\luapack\bin\Debug 然后glue.exe srl ...
- 【jquery easyUI 拓展
jquery-easyui本身没有提供列锁定/解锁的接口,并且其原有的列隐藏/显示在符合表头的情况下会出现错位,我在项目中遇到了这两个问题,在参考了网上许多解决方案后,编写了一个拓展插件,基本上解决了 ...
- C++知识整理
整理进度 1_ C++(31)中有很多没有整理的,找出来整理. 1.C++语言基础 C++中的头文件(.h) STL基本使用总结 C++里的花括号{},块:{}中的变量只在{}中有效 C++类型转换: ...