【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(至少包括两个数).没多久 ...
随机推荐
- ctfshow 1024杯 部分web题解
------------恢复内容开始------------ 今年1024忙得厉害,去大上海参加geekpwn膜拜大佬,几家平台的题目没怎么好好看.特别是小破站的比赛拉跨的一批,bytectf的web ...
- socket 参考文档
socket.io 中文手册,socket.io 中文文档转载于:http://www.cnblogs.com/xiezhengcai/p/3956401.html 服务端 io.on('connec ...
- java数据结构-11循环双端队列
@SuppressWarnings("unchecked") public class CircleDeque<E> { private int front; priv ...
- Windows 端口被占用,但进程号对应的进程不存在,使用Get-Process来查找进程挺方便的
Windows上很少安装数据库,这次遇到一个小问题:数据库启动之后提示: 警告: 无法为 "*" 创建监听套接字 致命错误: 无法创建TCP/IP套接字 日志: 数据库系统已关闭 ...
- final,static,this,super 关键字总结
一.final 关键字 final关键字主要用在三个地方:变量.方法.类. 1.对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改:如果是引用类型的变量,则在对其初始 ...
- python_for_else_return
def login(): # 登录 # 登录 输入用户名密码 # 和self.user_list作比对 while True: username = input('用户名 :') # password ...
- SSH个人小结
初学SSH的一些总结,主要来源于谷歌搜索和鸟叔的教程http://cn.linux.vbird.org/linux_server/0310telnetssh_2.php 以及阮一峰的博客http:// ...
- selenium之 定位以及切换frame(iframe)(转)
frame标签有frameset.frame.iframe三种,frameset跟其他普通标签没有区别,不会影响到正常的定位,而frame与iframe对selenium定位而言是一样的,seleni ...
- python菜鸟教程学习4:基本数据类型
变量:python中的变量不需要声明,但在使用前都必须要赋值,变量赋值之后才会被创建 在python中变量是没有类型的,所有的数据类型是对内存中对象的类型. 赋值:使用等号=来给变量赋值 python ...
- SpringBoot Redis切换数据库遇到的坑
项目不同业务的redis数据存在不同的库中,操作数据需要切换redis库,在网上找了一段代码,确实可以切换数据库.但是使用一段时间后发现部分数据存储的数据库不正确,排查后发现setDatabase是线 ...