题目描述

给出长度为 \(N\) 的序列 \(A=(A_1,A_2,\dots,A_N)\) 以及一个整数 \(K\)

存在 \(2^{N-1}\) 种方法将 \(A\) 分成若干个连续子区间。有多少划分方法满足没有任何一个划分出的子区间元素和为 \(K\)?请输出这个值模 \(998244353\) 的结果。

这里,“将 \(A\) 分成若干个连续子区间”的含义如下:

  • 随意选择一个整数 \(k\space 1\le k\le N\) 作为序列长度,并且随意选择一个满足条件 \(1=i_1<i_2<\dots<i_k<i_{k+1}=N+1\) 的整数序列 \((i_1,i_2,\dots,i_k,i_{k+1})\)
  • 对于每个满足 \(1\le n\le k\) 的整数 \(n\),第 \(n\) 个被划分出来的子区间是由提取序列 \(A\) 中的第 \(i_n\) 到第 \((i_{n+1}-1)\) 个元素得到的。

举个例子,以下是序列 \(A=(1,2,3,4,5)\) 的若干可行划分方案:

  • \((1,2,3),(4),(5)\)
  • \((1,2),(3,4,5)\)
  • \((1,2,3,4,5)\)

输入格式

从标准输入输出流输入,格式如下:

$ N \space K $

$ A_1 \space A_2 \space \dots \space A_N $

输出格式

请输出答案模 \(998244353\) 的结果。

输入输出样例 #1

输入 #1

3 3
1 2 3

输出 #1

2

输入输出样例 #2

输入 #2

5 0
0 0 0 0 0

输出 #2

0

输入输出样例 #3

输入 #3

10 5
-5 -1 -7 6 -6 -2 -5 10 2 -10

输出 #3

428

说明/提示

  • \(1 \leq N \leq 2 \times 10^5\)
  • \(-10^{15} \leq K \leq 10^{15}\)
  • \(-10^9 \leq A_i \leq 10^9\)
  • 全部输入为整数

对样例 1 的解释

以下是符合题目要求的 \(2\) 种划分方案。

  • \((1),(2,3)\)
  • \((1,2,3)\)

Author: Redshift_Shine


题解

\(F(x)\) 为长度为 \(x\) 的序列分为若干子序列的方法数,\(f(x)\) 为”没有任何一个划分出的子区间元素和为 \(K\) “的条件下的方法数。

对于 \(F(x)\)

\(x = 1\)
\((1)\)

\(x = 2\)
\((1) (2)\)
\((1, 2)\)

\(x = 3\)
\((1) (2) (3)\)
\((1) (2, 3)\)
\((1, 2) (3)\)
\((1, 2, 3)\)

通过朴素的观察,可以知道 x = 2 时的分类组合,可以看作时 x = 1 时的每个组合加上数字 2,再加上一个全集 \((1, 2)\)。同理 x = 3时的分类组合可以看作 x = 1 时的每一个组合加上数字 2, 3,x = 2 时的每一个组合加上数字 3,再加上一个全集\((1, 2 ,3)\)

\(x = 2\)
\((1) \rightarrow (1, 2)\) // x = 1 的组合
\((1, 2)\)

\(x = 3\)
\((1) \rightarrow (1, 2, 3)\) // x = 1 的组合
(1) \((2) \rightarrow(1) (2) (3)\)
\((1, 2) \rightarrow (1, 2) (3)\) // x = 2 的组合
\((1, 2, 3)\)

\(F(i) = \sum_{j = 1} ^ {i - 1} F(j) + 1\) ,则 \(f(i) = \sum_{s_i-s_j \neq k}f(j) + (s_i==k?1:0)\)\(s_i-s_j\neq k\) 的条件过于离散,正难则反,\(f(i) = sum-\sum_{s_i-k}^{j}f(j)\),设 \(sum\)\(1\)\(i-1\) 的合理分配方法总和,设 \(B_i\)\(sum\) 中的第 \(i\) 组合理分配,即\(B_i:b_1,b_2 \cdots, b_m\),则 \(B_i\) 加上 \(a_i\) 对应的分配方法 $ C_j \(是否符合条件,则需判断\) b_m + a_i = k$ 是否成立,即是否存在一个 j 满足 \(s_i - s_j = k\)。设 \(mp\) 记录每一个 \(s_i\) 对应的$ f_i$ 的和,\(f(i) = sum-mp[s_i-k]\)\(s_i == k\) 也不符合条件,所以 \(mp[0] =1\)

#include<iostream>
#include<map>
using namespace std;
typedef long long ll;

const int N = 2e5 + 10;
const int mod = 998244353;

ll n, k, sum;
ll a[N], s[N];
map<ll, ll> mp;

int main() {
	cin >> n >> k;
    for (int i = 1; i <= n; i++) {
		cin >> a[i];
    	s[i] = s[i - 1] + a[i];
    }
    mp[0] = 1, sum = 1;//空集也符合分配要求
    for (int i = 1; i <= n; i++) {
		f[i] = (sum - mp[s[i] - k] + mod) % mod;
        mp[s[i]] = (mp[s[i]] + f[i]) %mod;
        sum += f[i];
    } 
}