Codeforces Global Round 17 - D. Not Quite Lee

裴蜀定理 + lowbit

Problem - D - Codeforces

题意

定义一个包含 m 个元素的数组 b 是好的,当且仅当满足以下两个条件

  1. 对于 b[i], 存在一个长度为 b[i] 的连续的段(如 b[i]=4, [1,2,3,4], [-1,0,1,2]等就是符合条件的)
  2. 对于这 m 个段,sumi 记为这一段的数字和,并满足 sumi=0]

给定一个长度为 n(1<=n<=2105) 的数组 a[i],求 a2n1 个非空子序列组成的数组中,有多少个是好的

思路

  1. 对于 a[i] 而言,设选取的一段的第一个数是 xi, 则 sumi=aixi+ai(ai1)2

  2. 若选了 a 数组的 k 个数,记为 c1,c2...ck

    sumi=0cixi=ci(ci1)2

​ 根据裴蜀定理,设 g=gcd(c1,c2,...,ck), 则要满足 gci(ci1)2

  1. 如果 ci 中存在奇数,则 g 也一定是奇数,所以右边的除以2不影响整除的性质,又因为 gci, 因此 gci(ci1)2 恒成立

    所以奇数部分对方案数的贡献就是 2odd (也可以感性考虑,如果存在一个奇数,那么它和其余所有的偶数共有奇数个数,把它们按关于 0 对称排列即可;其余的奇数也关于 0 对称排列)

  2. 现在只关心偶数部分,因为 gci, 问题是右边的除以 2 之后还能否满足 gci(ci1)2,(即关心的是 ci 的含 2 量) 由于 ci1 为奇数,对除以 2 而言没有意义,不用考虑;

  3. 现在转化为 gci2 是否成立,记 lowb[x] 为能整除 x 的最高的 2 的幂次,例如 lowb[8]=3,lowb[16]=4

    lowb[g]<=lowb[ci]

    1. lowb[ci]>lowb[g], 那么 ci2 仍能被 g 整除
    2. lowb[ci]==lowb[g], 需要偶数个相等的 ci 才能使 gci2 (需要用到 (n0)+(n2)+(n4)+...=2n1 来优化)

    代码

#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;
}
posted @   hzy0227  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!
点击右上角即可分享
微信分享提示