【ACwing 100】InDec序列——差分
(题面来自AcWing)
给定一个长度为 n 的数列 a1,a2,…,an,每次可以选择一个区间 [l,r],使下标在这个区间内的数都加一或者都减一。
求至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列可能有多少种。
输入格式
第一行输入正整数n。
接下来n行,每行输入一个整数,第i+1行的整数代表ai。
输出格式
第一行输出最少操作次数。
第二行输出最终能得到多少种结果。
数据范围
0<n≤105,
0≤ai<2147483648(因为不开long long再次见到了祖宗)
看到题面之后的第一想法是差分之后暴搜方案,每次从(1~n + 1)选不同的两个数+1/-1,目标状态是d_2~d_n全部为0。然而数据范围显然不能接受。考虑序列操作的本质:我们要将差分序列d中除第一项外全部变为0,显然最优的方案是在d_2~d_n中优先选择一个负数、一个正数,分别+1、-1;设p、q分别为d中正、负项之和的绝对值,那么如上的第一种操作会把p、q中较小的一方降为0,这个过程最多执行min(p, q)次。之后正/负项中有一方会有剩余,我们可以选择把d_1与剩余项一同操作(相当于把原序列的某个前缀全部+1/-1),也可以选择d_(n+1)与剩余项一同操作(相当于操作后缀),最终都可以实现d_2~d_n全部为0。这一步操作最多执行|p - q|次。那么总的操作次数ans1满足:
ans1 = min(p, q) + |p - q| = max(p, q)
第二问要求统计在满足最小步数的情况下,可能产生的序列种类。由于最后序列每一项都相同,而d[1] = a[1],我们只要考虑最后d[1]有多少种即可。显然,上述最短操作过程不分先后,并且第一种操作不会对d[1]产生影响。考虑执行第二种操作后d[1]可能的取值:d[1]最多被增加/减少|p - q|次,最少被操作0次,并且d[1]可以被操作[0, |p - q|]中的任意多次。因此d[1]的取值有|p - q| + 1种,即ans2 = |p - q| + 1。
代码:
- #include <cstdio>
- #include <iostream>
- #include <cmath>
- #define rep(i, a, b) for(int i = a; i <= b; ++i)
- #define per(i, b, a) for(int i = b; i >= a; --i)
- #define maxn 100010
- using namespace std;
- long long d[maxn], a[maxn];
- int main() {
- int n;
- ios::sync_with_stdio(0);
- cin >> n;
- long long p = 0, q = 0;
- rep(i, 1, n) {
- cin >> a[i];
- d[i] = a[i] - a[i - 1];
- if (i - 1)
- d[i] >= 0 ? p += d[i] : q += -d[i];
- }
- cout << max(p, q) << endl << abs(p - q) + 1;
- return 0;
- }
【ACwing 100】InDec序列——差分的更多相关文章
- AcWing 100. 增减序列
给定一个长度为n的数列每次可以选择一个区间 [l,r],使下标在这个区间内的数都加一或者都减一. 求至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列可能有多少 ...
- IncDec序列:差分+贪心
IncDec序列 题目描述: 给定一个长度为 n 的数列 a1,a2,…,an,每次可以选择一个区间[l,r],使下标在这个区间内的数都加一或者都减一. 求至少需要多少次操作才能使数列中的所有数都一样 ...
- [leetcode]1109. 航班预订统计(击败100%用户算法-差分数组的详解)
执行用时2ms,击败100%用户 内存消耗52.1MB,击败91%用户 这也是我第一次用差分数组,之前从来没有碰到过,利用差分数组就是利用了差分数组在某一区间内同时加减情况,只会改变最左边和最右边+1 ...
- AcWing:146. 序列(小根堆 + 数学归纳 + 贪心)
给定m个序列,每个包含n个非负整数. 现在我们可以从每个序列中选择一个数字以形成具有m个整数的序列. 很明显,我们一共可以得到nmnm个这种序列, 然后我们可以计算每个序列中的数字之和,并得到nmnm ...
- Acwing-100-IncDec序列(差分)
链接: https://www.acwing.com/problem/content/102/ 题意: 给定一个长度为 n 的数列 a1,a2,-,an,每次可以选择一个区间 [l,r],使下标在这个 ...
- 100 IncDec序列
IncDec序列 Description 给定一个长度为 n 的数列 a1,a2,-,an,每次可以选择一个区间 [l,r],使下标在这个区间内的数都加一或者都减一. 求至少需要多少次操作才能使数列中 ...
- 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!
// test20.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...
- AcWing 1277. 维护序列
#include <bits/stdc++.h> #define ll long long #define N 4000010 using namespace std; ll t[N],a ...
- 剑指offer41:所有和为S的连续正数序列,例如,有多少种连续的正数序列的和为100
1 题目描述 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100.但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数).没多久 ...
随机推荐
- MySQL全面瓦解4:数据定义-DDL
前言 SQL的语言分类主要包含如下几种: DDL 数据定义语言 create.drop.alter 数据定义语言 create.drop.alter 语句 . DML 数据操纵语言 insert.de ...
- 老司机谈谈如何学习STM32嵌入式系统
一.嵌入式系统的概念 着重理解"嵌入"的概念 ,主要从三个方面上来理解. 首先,从硬件上,"嵌入"是基于CPU的处围器件的,整合到CPU芯片内部,就好比早期基于 ...
- OpenCascade拓扑对象之:有向边和共边
@font-face { font-family: "Times New Roman" } @font-face { font-family: "宋体" } @ ...
- Java安全之RMI反序列化
Java安全之RMI反序列化 0x00 前言 在分析Fastjson漏洞前,需要了解RMI机制和JNDI注入等知识点,所以本篇文来分析一下RMI机制. 在Java里面简单来说使用Java调用远程Jav ...
- Python爬虫简单实现CSDN博客文章标题列表
Python爬虫简单实现CSDN博客文章标题列表 操作步骤: 分析接口,怎么获取数据? 模拟接口,尝试提取数据 封装接口函数,实现函数调用. 1.分析接口 打开Chrome浏览器,开启开发者工具(F1 ...
- Thinkphp3.2 cms之文章模块
二.文章模块 <?php namespace Admin\Controller; use Think\Controller; class NewController extends Common ...
- Linux sar命令参数详解
转载自http://www.chinaz.com/server/2013/0401/297942.shtml sar(System Activity Reporter系统活动情况报告)是目前 Linu ...
- HTML5+CSS3城市场景动画
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- HTML/css清除浮动的几种方式
浮动在HTML/CSS布局中十分常见,虽然浮动布局可以实现很多有用的排版效果,但是浮动的元素脱离了文档流,可能造成包含块高度塌陷.下方行框上移等行为.因此在使用浮动实现想要的效果后,通常还需要清除浮动 ...
- 2. Hive常见操作命令整理
该笔记主要整理了<Hive编程指南>中一些常见的操作命令,大致如下(持续补充中): 1. 查看/设置/修改变量2. 执行命令3. 搜索相关内容4. 查看库表信息5. 创建表6. 分区7. ...