ABC370 E - Avoid K Partition

求一个序列的合法划分方案数。一种划分合法当且仅当没有一个子串的和是 \(k\)。

由于是否存在子串和为 \(k\) 很重要,因此考虑将它加入状态设计中,记 \(f[i][0/1]\) 表示 \(1 \sim i\),\(i\) 处结束,还没有 / 已有和为 \(k\) 的子段,方案数。

用 \(s[i]\) 表示前缀和,得到朴素的 \(O(n^2)\) 转移:

\[f[i][0] = \sum_{0 \le j \lt i \cap s[i] - s[j] \ne k} f[j][0]
\]
\[f[i][1] = \sum_{0 \le j \lt i}f[j][1] + \sum_{0 \le j \lt i \cap s[i] - s[j] = k} f[j][0]
\]

发现 \(a[i], k\) 可以是负数,因此 \(s\) 没有单调性,不好直接找每个 \(i\) 对应的 \(j\),可能也不止一个。但对于固定的 \(i\),\(s[j] = s[i] - k\) 是固定的,因此我们可以对于每个 \(s[j]\) 都实时维护 \(\sum{f[j][0]}\),值域较大,用 \(map\) 实现就 ok。最后对 \(f[][0/1]\) 分别记录前缀和就可以做到 \(O(nlogn)\)。转移没什么变化,直接看代码,最后记得取模变正数。

#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l);i<=(r);++i)
#define G(i,r,l) for(int i(r);i>=(l);--i)
#define int ll
using namespace std;
using ll = long long;
const int N = 2e5 + 5;
const int mod = 998244353;
int f[N][2], s[N];
int n, k, a[N];
map<int, int> mp;
signed main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> n >> k;
F(i, 1, n) {
cin >> a[i];
s[i] = s[i - 1] + a[i];
}
int sm0 = 1, sm1 = 0;
mp[0] = 1;
F(i, 1, n){
int ret = mp[s[i] - k];
f[i][0] = (sm0 - ret) % mod;
f[i][1] = (sm1 + ret) % mod;
(mp[s[i]] += f[i][0]) %= mod;
(sm0 += f[i][0]) %= mod;
(sm1 += f[i][1]) %= mod;
}
cout << (f[n][0] + mod) % mod << '\n';
return fflush(0), 0;
}

ABC370 E - Avoid K Partition的更多相关文章

  1. Lintcode: Partition Array

    Given an array "nums" of integers and an int "k", Partition the array (i.e move ...

  2. Partition Array

    Given an array nums of integers and an int k, partition the array (i.e move the elements in "nu ...

  3. 【Offer】[40] 【最小的K个数】

    题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 输入n个整数,找出其中最小的k个数.例如,输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 牛客网刷题地 ...

  4. 线性时间求取第 K 大数

    求 Top K 的算法主要有基于快速排序的和基于堆的这两种,它们的时间复杂度都为 \(O(nlogK)\).借助于分治思想,以及快速排序的区间划分,我们可以做到 \(O(n)\) 时间复杂度.具体算法 ...

  5. 用Java来写常见的排序算法

    随着校招的临近 算法是校招中很重要的一个部分 总结了常见几种排序算法,各种算法的时间复杂度和空间复杂度大家也需要多了解下 package com.huwei.sort; /** * 各种排序算法 * ...

  6. Python字符串str的方法使用

    #!usr/bin/env python# -*-coding:utf-8-*-#字符串通常用双引号或单引号来表示:'123',"abc","字符串"#str字 ...

  7. List.Sort以及快速排序ZZ

    经常看到有人因为使用.net中的集合类处理海量数据时性能不够理想,就武断的得出.net不行,c#也不行这样的结论.对于.net framework这样的类库来说,除了性能以外,通用性和安全性同样重要, ...

  8. Java中各种排序算法

    package org.rut.util.algorithm.support; import org.rut.util.algorithm.SortUtil; /** * @author treero ...

  9. c语言:快速排序

    练手代码(分治实现): input: int input[] = {12,6,3,9,10,6,2}; output: ======================= len = 7 input[0] ...

  10. 排序算法总结(C++版)

    总结下学过的排序算法,方便以后用到. 1.插入排序——将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表. void insertSort(int a[],int len) { ; ...

随机推荐

  1. CH06_函数

    CH06_函数 概述 作用:将一段可复用的代码封装起来,减少代码重复. 一个较大的程序,一般分为若干个程序块,每个模块实现特定的功能. 函数的定义 函数的定义一般主要有5个步骤: 返回值类型 函数名 ...

  2. Synology NAS GitLab 配置

    安装 安装的时候会提示服务器名.root用户名等,这步服务器名千万不要写错,不然会登不上去,提示 502. root 密码 网上有很多说 root 密码怎么获取的,但是都不适用. 实际上是第一个访问 ...

  3. CSS2基础(part-1)

    CSS2基础 基础 简介 [全称]Cascading Style Sheets,又名层叠样式表 层叠:一层一层涂上去 表:列表 样式:如文字大小,颜色,元素宽高等. CSS 描述了在屏幕.纸质.音频等 ...

  4. 使用inno setup 打包Pyinstaller生成的文件夹

    背景:pyinstaller 6.5.0.Inno Setup 6.2.2 1. 需要先使用pyinstaller打包,生成包括exe在内的可执行文件夹 注意:直接使用pyinstaller打包,生成 ...

  5. RxJS 系列 – Mathematical and Aggregate Operators

    前言 前几篇介绍过了 Creation Operators Filtering Operators Join Creation Operators Error Handling Operators T ...

  6. Angular – ESLint

    介绍 Angular wrap 了一层 ESLint, 定义了一些 best practice guide. 这篇说说如何 setup 它. 这个 ESLint 并不是 under Angular T ...

  7. Azure – WAF (Web Application Firewall)

    前言 最近有客户想购买 Azure 的 Web Application Firewall (WAF), 来防 SQL Injection, XSS 攻击. 一开始我是觉得没什么必要, 毕竟什么年代了, ...

  8. Ubuntu 64系统编译android arm64-v8a 的openssl静态库libssl.a和libcrypto.a

    #!/bin/bash # Cross-compile environment for Android on ARM64 and x86 # # Contents licensed under the ...

  9. 【VMware VCF】使用 VCF Import Tool 将现有 vSphere 环境转换为管理域。

    VMware Cloud Foundation 5.2 发布并引入了一个新的功能,借助 VCF Import Tool 工具可以将现有 vSphere 环境直接转换(Convert)为管理工作负载域或 ...

  10. Java如何将Object转换成指定Class对象

    在Java中,将Object转换为指定类型的Class对象实际上是两个不同概念的操作: 将Object实例转换为特定类型的实例:这通常涉及到类型转换(如(MyType) myObject)或者通过反射 ...