首页 > 其他分享 >Balance Addicts 题解

Balance Addicts 题解

时间:2023-11-08 16:35:47浏览次数:45  
标签:cnt include int 题解 Addicts choose 序列 Balance mod

Balance Addicts

题目大意

给定序列 \(a\),求有多少种合法的划分方案。

定义一种划分方案是合法的当且仅当划分出的各段序列的和构成回文序列。

思路分析

一种不太一样的做法。

我们先对 \(a\) 做一遍前缀和,得到 \(s\)。

观察各段序列的和形式:

\[s_{p_1},s_{p_2} - s_{p_1},s_{p_3}-s_{p_2},...,s_{p_k}-s_{p_{k-1}} \]

其中,\(p_i\) 是第 \(i\) 段的结尾下标,\(k\) 是划分出的段数。

因为这个序列构成回文序列,因此我们有:

\[\begin{cases} s_{p_1}=s_{p_k}-s_{p_{k-1}}\\ s_{p_2}-s_{p_1}=s_{p_{k-1}}-s_{p_{k-2}}\\ ...\\ s_{p_{m}}-s_{p_{m-1}} = s_{p_{k-m+1}} - s_{p_{k-m}} \end{cases}\]

移项,得到以下等式:

\[s_{p_m}+s_{p_{k-m}}=s_{p_{m-1}}+s_{p_{k-m+1}}=...=s_{p_2}+s_{p_{k-2}}=s_{p_1}+s_{p_{k-1}}=s_{p_k}=s_n \]

也就是说,我们选出的序列是回文序列的充要条件是:

\[\boxed{s_{p_i}+s_{p_{k-i}}=s_n} \]

因为 \(a_i\ge0\),所以 \(s\) 单调不减,也就是说,\(s\) 中相同的值均相邻

那么我们对 \(s\) 的每一段值分别考虑。我们可以发现,\(s\) 的每一段值之间互不影响,也就是说,对于 \(s\) 中的一种值我们计算且只计算一次答案。

对于一种值 \(x\),设 \(cnt(x)\) 表示 \(x\) 在 \(s\) 中的出现次数,那么它对答案的贡献就是:

\[\sum_{i=1}^{cnt(x)}{cnt(x)\choose i}{cnt(s_n-x)\choose i} \]

也就是枚举这种值放几个到回文序列中去,用乘法原理和加法原理组合出结果。这里默认 \(cnt(x)\le cnt(s_n-x)\),不满足交换一下就可以了。

然后考虑范德蒙德卷积,也就是:

\[\sum_{i=1}^{cnt(x)}{cnt(x)\choose i}{cnt(s_n-x)\choose i}=\sum_{i=1}^{cnt(x)}{cnt(x)\choose cnt(x)-i}{cnt(s_n-x)\choose i}={cnt(x)+cnt(s_n-x)\choose cnt(x)} \]

(这里其实麻烦了,直接枚举也是可以的,因为 \(\sum cnt(x)=n\)。是我脑抽了。)

因此,我们可以得出答案的最终表达式为:

\[\prod_{x\in V} {cnt(x)+cnt(s_n-x)\choose cnt(x)} \]

其中,\(V\) 表示 \(s\) 的值域集合,注意 \(x\) 和 \(s_n-x\) 只能计算一次。

当 \(s_n\) 是偶数时,会出现 \(s_{p_i}=s_{p_{k-i}}=\dfrac{1}{2}s_n\) 这样的情况,因此这时需要额外乘上 \(2^{cnt(\frac{1}{2}s_n)}\),也就是等于 \(\dfrac{1}{2}s_n\) 的数可以随便选的方案数。

代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <map>

using namespace std;
const int N = 200200, L = 200000, mod = 998244353;
#define inf 0x3f3f3f3f
#define int long long

int n, ans = 1, T;
int a[N], sum[N], fac[N], inv[N];

map <int, int> mp;

int q_pow(int a, int b){
    int res = 1;
    while (b) {
        if (b & 1) res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}

int C(int n, int m){
    if (m > n) return 0;
    return fac[n] * inv[n - m] % mod * inv[m] % mod;  
}

signed main(){
    fac[0] = 1;
    for (int i = 1; i <= L; i ++) fac[i] = fac[i - 1] * i % mod;
    inv[L] = q_pow(fac[L], mod - 2);
    for (int i = L; i >= 1; i --) inv[i - 1] = inv[i] * i % mod;
    scanf("%lld", &T);
    while (T --) {
        mp.clear(); ans = 1;
        scanf("%lld", &n);
        for (int i = 1; i <= n; i ++) scanf("%lld", &a[i]);
        for (int i = 1; i <= n; i ++) sum[i] = sum[i - 1] + a[i];
        for (int i = 1; i < n; i ++) mp[sum[i]] ++;
        int pos = 1;
        while (sum[pos] * 2 < sum[n]) {
            if (sum[pos] != sum[pos + 1]) 
                ans = ans * C(mp[sum[pos]] + mp[sum[n] - sum[pos]], mp[sum[pos]]) % mod;
            pos ++;
        }
        if (sum[n] % 2 == 0) ans = ans * q_pow(2, mp[sum[n] / 2]) % mod;
        cout << ans << '\n';
    }
    return 0;
}

标签:cnt,include,int,题解,Addicts,choose,序列,Balance,mod
From: https://www.cnblogs.com/TKXZ133/p/17817685.html

相关文章

  • P2146 [NOI2015] 软件包管理器 题解
    [NOI2015]软件包管理器题目背景Linux用户和OSX用户一定对软件包管理器不会陌生。通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个软件包的安装所依赖的其它软件包),完成所有的配置。Debi......
  • 【洛谷 P4414】[COCI2006-2007#2] ABC 题解(排序)
    [COCI2006-2007#2]ABC题面翻译【题目描述】三个整数分别为。这三个数字不会按照这样的顺序给你,但它们始终满足条件:。为了看起来更加简洁明了,我们希望你可以按照给定的顺序重新排列它们。【输入格式】第一行包含三个正整数,不一定是按这个顺序。这三个数字都小于或等于。第二行包......
  • 前端计算数字精度丢失问题解决方法记录 | 京东云技术团队
    在日常一些需求中,总会遇到一些需要前端进行手动计算的场景,那么这里需要优先考虑的则是数字精度问题!具体请看下面截图如图所示,在JavaScript进行浮点型数据计算当中,会出现计算结果“不正确”的现象。我们知道浮点型数据类型主要有:单精度float、双精度double。浮点型简单来说就是表示......
  • 23级ACM第二次招新测试题解
    A.lyynuu思路:先了解子序列的概念:在数学中,某个序列的子序列是从最初序列通过去除某些元素但不破坏余下元素的相对位置(在前或在后)而形成的新序列接下来我们就思考什么样的字符串可以让子序列lynu形成的数量最多,显然当相同字符连在一起时可以形成尽可能多的lynu,例如:llyy......
  • 题解 P4755 Beautiful Pair
    洛谷。题意显然。分析首先考虑到分治,那么问题就在于如何维护经过某个结点的方案数。利用从中间结点向两端的前缀后缀最大值,接下来我们对左端点的每一个结点考虑连向右侧的方案数。考虑分类讨论,令左端点为\(i\),右端点为\(j\)。假如\(mx_i>mx_j\),那么我们整个区间的最大......
  • Maximum Balanced Circle
    here首先根据题意,我们不难有数字是连续的这种感悟。而且限制是值域上的,从下标入手发现难以突破,便从值域上入手。从小到大考虑每个数字,然后dp,可以参考这篇题解。至于方案的输出,有两种情况。只有自己\(i\)和\(i-1\),直接输出即可。有自己和\(i-1\)的环,定义print输出环,且最大......
  • 23级ACM实验室第一次招新测试题解
    A.还是HelloWorld?思路:无代码:c++:#include<bits/stdc++.h>usingnamespacestd;intmain(){ cin.tie(0)->ios::sync_with_stdio(0); cout<<"Hello,World!"<<endl; return0;}B.这题真不难,放轻松~思路:无代码:C++:#include<bits/st......
  • HDFS Balancer存储水位稳定性原理与实践
    1.背景在HDFS分布式系统中,经常会上线新的datanode以环境集群容量不足的问题。但是往往旧datanode水位较高,甚至爆满无法写入,新datanode非常空闲,导致旧机器无法写入数据,集群的流量集中到新datanode中,造成新datanode网络延迟。为了解决上述问题,可以通过Balancer工具定时讲高水位dat......
  • [ARC105E] Keep Graph Disconnected 题解
    题意给定一张由\(N\)个点和\(M\)条边组成的简单无向图\(G\),定义一个无向图是好的当且仅当这张图满足以下条件:\(1\)号节点和\(N\)号节点不联通图中不存在重边和自环现有两人轮流采取操作,每轮操作如下:选择两个点\(u,v\),将边\((u,v)\)加入图\(G\)中当一方无......
  • 【题解】HNOI2012 - 集合选数
    HNOI2012-集合选数https://www.luogu.com.cn/problem/P3226不算难的非显然状压dp。首先根据限制条件建图,\((x,2x),(x,3x)\)连边,表示边上相邻两个点不能同时选,然后一组独立集就是一个可行的集合。发现画出来的图是若干个部分网格图,每个连通块最小的点都是与\(6\)互质的数......