CF2077C Binary Subsequence Value Sum 题解
前言:
(虚假的想象学竞赛,实际的数学竞赛)
题意:
给出一个长度为 \(n\) 的二进制序列,我们对于每一个分割点(可以看做在元素与元素之间),其贡献为分割点右边的 \(cnt_1 - cnt_0\) 与左边的 \(cnt_1 - cnt_0\) 乘积,并且定义这个序列的得分为这个序列所有分割点贡献的最大值。
现在希望你求出给定的长度为 \(n\) 的二进制序列的所有子序列的贡献之和(子序列可以不连续,也就是类似于子集的定义)。同时我们有 \(q\) 次询问,每一次都会修改这个二进制序列上的某一个值(使其异或上 \(1\)),对于每一次修改之后都要回答上述的贡献之和。
思路:
显然的,对于一个固定的序列,我们可以 \(O(len)\) 暴力去做,但是很明显非常不优秀,那我们考虑一步一步优化。首先需要明确的是,对于一个固定的序列,其 \(cnt_1 - cnt_0\) 总为一个定值,我们记为 \(p\)。假设任意分割点左边的贡献为 \(a\),右边的为 \(b = (p-a)\)。那么贡献即为:
\]
我们需要得到 \(f(a)_{\max},a\in[0,p]\),其实这个地方的定义域是不严谨的,只是这么写方便理解。那么一般来说最值在 \(a=\frac{p}{2}\) 的时候取到,显然这是在定义域之内的。又因为 \(a\) 是整数,所以我们某一个固定序列的得分即为:
\]
现在考虑如何形式化的表示所有子序列的得分。令 \(x\) 为这个长度为 \(n\) 的序列的 \(cnt_1\) ,\(y\) 为 \(cnt_0\) ,显然 \(x+y=n\) ,给出式子:
\]
其中后面中括号包起来很奇怪的那一坨的意义是判断 \(i-j\) 是否为奇数。想等式比较难,但是我觉得等式都列出来了应该不难理解,至于 \(\frac{1}{4}\) 的由来是两个 \(\frac{i-j}{2}\) 提出去的。
现在好像复杂度还是不够优秀,没事我们有数学牢大的帮助。先不考虑后面判断奇偶的问题,只考虑前面的式子。考虑把完全平方展开,对于 \(i^2\) 和 \(j^2\) 发现形式一样,可以只考虑一种。在给出最终推到之前,需要给出一个重要的等式:
\]
考虑组合意义(双射)证明,右边式子可以看做先在 \(x\) 个里面选择 \(i\) 个,然后在 \(i\) 个里面选择 \(1\) 个。左边可以看做先在 \(x\) 里面选择 \(1\) 个,然后在剩下的里面选择 \(i-1\) 个,可以证明的是,这是双射的。
运用相同的思想,可以得到:
\]
唯一需要的技巧就是把 \(i(i-1)+i\) 分开算。
那么开始暴力简化式子之后就可以得到:
\]
这个式子的推导过程是有趣的,但是太长了,请根据上述前置等式自行推导(对于第一次接触组合推导的组合小白来说,这是具有启发性的)。
然后还需处理一个问题,就是那个判断奇偶性的部分,怎么快速处理。我们这样考虑,假设外层的 \(i\) 一直枚举,很显然,要满足 \(i+j\) 是一个奇数,那么必然有内层的 \(j\) 是一个偶数,反之同理,也就是内层存在的贡献应为:
\sum_{j\equiv1\pmod 2}^y\dbinom{x}{j},\left(i\equiv0\pmod2\right)\\
\sum_{j\equiv0\pmod 2}^y\dbinom{x}{j},\left(i\equiv1\pmod2\right)
\end{cases}
\]
这个两个式子应该是非常著名的,他们的贡献都为 \(2^{y-1}\),又因为外层的总贡献为 \(2^x\) 所以总贡献就为 \(2^{n-1}\) ,最终答案减去他就好啦,所以:
\]
然后最后就只剩下单个位置修改的问题了,很简单,修改了之后改变一下 \(cnt_{0/1}\) 的值就好啦。
Code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define LL long long
inline int read(){
char c=getchar();bool f=0;int x=0;
while(c > '9' || c < '0') f|=c=='-',c=getchar();
while(c >= '0'&&c <= '9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
if(f) x=-x;return x;
}
const int N = 2e5 + 10;
const int MOD = 998244353;
char s[N];
int inv2 = (MOD + 1) / 2,p2[N],n,q;
LL cnt[2];
LL calc(LL x)
{
if(x == 0) return 0;
else if(x == 1) return x * p2[n - x] % MOD * inv2 % MOD * inv2 % MOD;
else return (x * p2[x - 1] + x * (x - 1) % MOD * p2[x - 2]) % MOD * p2[n - x] % MOD * inv2 % MOD * inv2 % MOD;
}
void solve()
{
cnt[0] = cnt[1] = 0;
n = read(),q = read();
scanf("%s",s + 1);
for(int i = 1;i <= n;++i)
++cnt[s[i] - '0'];
while(q--)
{
int id = read();
--cnt[s[id] - '0'];
s[id] = '1' - (s[id] - '0');
++cnt[s[id] - '0'];
LL ans = 0;
ans = (calc(cnt[0]) + calc(cnt[1])) % MOD;
ans = ans - (cnt[0] * cnt[1] % MOD * p2[n - 1] % MOD + p2[n - 1] + MOD) * inv2 % MOD * inv2 % MOD;
ans = (ans % MOD + MOD) % MOD;
std::cout << ans << '\n';
}
}
int main()
{
int T;
T = read();
p2[0] = 1;
for(int i = 1;i <= N - 10;++i) p2[i] = (p2[i - 1] << 1) % MOD;
while(T--) solve();
return 0;
}
CF2077C Binary Subsequence Value Sum 题解的更多相关文章
- Codeforces Round #515 (Div. 3) E. Binary Numbers AND Sum
E. Binary Numbers AND Sum 题目链接:https://codeforces.com/contest/1066/problem/E 题意: 给出两个用二进制表示的数,然后将第二个 ...
- [LeetCode#110, 112, 113]Balanced Binary Tree, Path Sum, Path Sum II
Problem 1 [Balanced Binary Tree] Given a binary tree, determine if it is height-balanced. For this p ...
- Ural 1248 Sequence Sum 题解
目录 Ural 1248 Sequence Sum 题解 题意 题解 程序 Ural 1248 Sequence Sum 题解 题意 给定\(n\)个用科学计数法表示的实数\((10^{-100}\s ...
- Hdoj 1003.Max Sum 题解
Problem Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum ...
- Binary Tree Path Sum
Given a binary tree, find all paths that sum of the nodes in the path equals to a given number targe ...
- 376. Binary Tree Path Sum【LintCode java】
Description Given a binary tree, find all paths that sum of the nodes in the path equals to a given ...
- LeetCode 930. Binary Subarrays With Sum
原题链接在这里:https://leetcode.com/problems/binary-subarrays-with-sum/ 题目: In an array A of 0s and 1s, how ...
- Binary Numbers AND Sum CodeForces - 1066E (前缀和)
You are given two huge binary integer numbers aa and bb of lengths nn and mmrespectively. You will r ...
- LeetCode Continuous Subarray Sum 题解 同余前缀和 Hash表
文章目录 题意 思路 特殊情况k=0 Source Code 1 Source Code 2 题意 给定一个数组和一个整数k,返回是否存在一个长度至少为2的连续子数组的和为k的倍数. 思路 和上一篇博 ...
- 【CF1445D】Divide and Sum 题解
题目链接 题意简介 将一个长度为 2n 的数列平均分为两个子数列 p 和 q 后,p 按从小到大排序,q 按从大到小排序. 排序后,记 p 为 \(\{x_i\}\) ,q 为 \(\{y_i\}\) ...
随机推荐
- 通过COM,用Python调用C#库
1.C#配置 (1)类库 (2)COM互操作打勾 (3)代码中类必须要有无参构造函数,否则不会注册成功!!! using System; using System.Runtime.InteropSer ...
- 取余(rem)和取模(mod)的区别
设 A rem B || A mod B 生成机制 取余:采取fix()函数,向0方向取整 取模:采取floor()函数,向无穷小方向取整 当A,B异号时(其实同号也是这个规律-) 取余:结果和A同号 ...
- MySQL的表空间释放
概述 最近为了对 MySQL 数据库磁盘占用瘦身,对一张近100GB表的历史数据进行了 delete 删除,删除了约2/3的数据,删除后发现该表占用的空间并未减少.通过下面语句查看该表的磁盘占用情况: ...
- 2.3.net core 工作流WorkFlow流程(流程节点附件设置)
流程节点附件设置 WikeFlow官网:http://www.wikesoft.com 有些流程要求某些节点必须上传附件. 你只需要在流程节点中配置附件的Key,附件名称,是否必传. 如下图: 文件存 ...
- Java 压缩成zip文件
综述 在< 把多个文件打包压缩成tar.gz文件并解压的Java实现>中介绍了如何把文件压缩车gz文件,这里介绍如何把文件压缩成zip文件.支持如下方式的压缩: 压缩单个文件 压缩文件夹下 ...
- 【Java】汉字转拼音
将汉字转成拼音及汉字首字母,可以使用jar包 pingyin4j,但是遇到多音节汉字就会有问题.如果使用大名鼎鼎的jpinyin,可以自动识别常见多音字,而且还支持简体转换为繁体,检查是简体还是繁体, ...
- 最适合初学者的简单JAVAWEB项目快速入门
最近学习了一段时间JavaWeb,但做项目一直做不出来.相信很多初学者都有和我一样的问题,即为什么我学了,但我不会做?以及如何做一个简单的Web项目?对于初学者来说,我感觉可能从我,一个初学者角度来回 ...
- C# 锁机制全景与高效实践:从 Monitor 到 .NET 9 全新 Lock
引言:线程安全与锁的基本概念 线程安全 在多线程编程中,保障共享资源的安全访问依赖于有效的线程同步机制.理解并处理好以下两个核心概念至关重要: 线程安全:指某个类.方法或数据结构能够在被多个线程同时访 ...
- Jenkinsfile_定义全局全量
一.通过def定义全局变量 注意:首行def定义的变量不能使用=赋值. def var pipeline { agent any stages { stage("定义var") { ...
- 高效安全迁移:PG高可用集群实战方案深度解析
PostgreSQL是一个开源的数据库管理系统,相比于其他开源数据库系统,PostgreSQL有更加丰富的数据类型和可扩展性,并因此被广泛采用.在实际工作中,若企业业务需求变动,则有可能面临PG高可用 ...