tk's blog
  • tk's blog Read Me
  • 算法相关
    • 数据结构
      • 【集训整理】 旋转treap模板
      • 二叉树及相关数据结构的java语言实现
      • 快乐树0x01:AVL树的java实现
      • 快乐树0x02 线段树实现(c++)
      • 链表的Java语言实现
    • 算法
      • DP的背包问题小结-java语言描述
      • 【集训整理】2-SAT问题 模板题
      • 【集训整理】Tarjan算法 模板题
      • 【集训整理】差分约束 模板题
      • 【集训整理】最近公共祖先LCA 模板题
      • 二分查找与二分答案-java实现
      • 动态规划-java语言练习一:暴力DP
      • 快速幂
      • 状态压缩DP-java描述
      • 差分
      • 乘法逆元
    • 题解
      • CFRound-GoodBye2022题解
  • java相关
    • Java与算法竞赛——注意事项摘录
    • java面向对象简要总结 一
    • java面向对象简要总结 三
    • java面向对象简要总结 二
  • 后端相关
    • Linux-Crontab命令
    • Spring Data JPA 使用方法
    • Spring集成Artemis实现JSM的异步消息传递
    • Spring使用自定义配置项
    • MIT6.824分布式系统Lab1.MapReduce笔记
    • MIT6.824分布式系统Lab2-Raft-A笔记
    • MIT6.824分布式系统Lab2-Raft-B笔记
  • 杂谈
    • 杂谈-关于2021
  • 杂项
    • c语言 scanf的返回值
    • 系统设计
  • 计科基础
    • 编译原理
      • 编译原理:词法分析笔记
    • CSAPP 第二章笔记
    • 计算机组成原理笔记
    • CSAPP Lab1. Datalab
    • CSAPP Lab2 Bomblab
  • C++每日一题
    • C++每日一题 Day 1 肥宅水
    • C++每日一题 Day 2 数字反转
    • C++每日一题 Day 3 理五的凡尔赛风气
    • C++每日一题 Day 4 我喜欢这个数
    • C++每日一题 Day 5 数字楼梯
    • C++每日一题 Day 6 插火把
    • C++每日一题 Day 7 贪吃蛇
    • C++每日一题 Day 8 蒙德最强战力
    • C++每日一题 Day 9 璃月七星选举
    • C每日一题 Day 2 肥宅水
    • C每日一题 Day 3 理五的凡尔赛风气
    • C语言每日一题 Day 1 荧妹好感队
由 GitBook 提供支持
在本页
  • 作用:
  • 例题:
  1. 算法相关
  2. 算法

差分

上一页状态压缩DP-java描述下一页乘法逆元

最后更新于2年前


差分是前缀和的逆运算。

差分数列,由该位置元素和前一个元素的差构成。

例子:

2 3 5 7 11 13 17 19

差分数列:2 1 2 2 4 2 4 2

作用:

用于将区间操作转换成单点操作,原本对区间的操作在差分数列上体现的是对1-2个单点的操作。

例如,对数列的前k项同时-1,差分数列上表现为对第1项减1,对第n+1项加1,其余项不变。

例题:

题意:给定一串序列,可以进行无限次操作:对前任意k个数减1或对后任意k个数减1,求是否能将这个数组的元素全部置0.

发现是前k个和后k个的区间问题,考虑维护差分,把原数列置零等同于把差分数列置零(第一项是0,剩下的项和第一项的差都是0)。

对差分数列来说,对前k个数减1只意味着对第1项减1,对第n+1项加1,其余项不变;对后k个数减1对差分数列只意味着对第k项减1。

容易发现,我们可以对任意正数做任意次减1,直到减到0为止;唯一的变数在于负数,某负数要加到0,只能靠减第一项来实现。所以只用判断第一项减到0时负数能不能都加到0就行了。

代码:

const int maxn = 30005;
int a[maxn],dif[maxn];
int main() {
	int t;
	cin >> t;
	while (t--) {
		int n; cin >> n;
		for (int i = 1; i <= n; i++) cin >> a[i];
		dif[1] = a[1];
		int tot = 0;
		for (int i = 2; i <= n; i++) {
			dif[i] = a[i] - a[i - 1];
			if (dif[i] < 0) tot-=dif[i];
		}
		if (a[1] >= tot) cout << "YES\n";
		else cout << "NO\n";
	}
}
Problem - D - Codeforces