参考链接:https://blog.csdn.net/hzk_cpp/article/details/80407014

题目链接:https://www.acwing.com/problem/content/102/

前缀和:

就是一个数组,要快速静态查询区间和,我们只要处理一个数组时A[i]=a[1]+a[2]+...+a[i].

A[1]=a[1]

A[2]=a[1]+a[2]

A[3]=a[1]+a[2]+a[3]

A[4]=a[1]+a[2]+a[3]+a[4]

......

例如:求[2,4]的区间和,A[4]-A[1]=a[2]+a[3]+a[4]=a[1]+a[2]+a[3]+a[4]-(a[1])

那么查询区间[l,r]的时候只要输出A[r]-A[l-1].

那么这是时候预处理是O(n)的,查询一次是O(1).

在很多情况下这种算法都是可行的,但是必须满足区间减法的性质.

代码预处理如下:

for (int i=1;i<=n;i++)
A[i]=A[i-1]+a[i];
差分:

只不过它可以配套前缀和使用.

差分是一种很巧妙的思想,它的主要用途是维护一个区间的快速修改(加减),但查询是单次的时候.O(n+m)

这种思想的主体就是维护一个数组A,其中A[i]=原数组a[i]-a[i-1].

那么就是刚好与前缀和有点像.

也是互逆的运算.

那么这怎么快速维护呢?

也就是说给区间[l,r]+num.

那么就是给开头A[l]+num,再给结尾A[r+1]-num.

很好理解啊.

那么实现如下:

void add(int l,int r,int num){
A[l]+=num;A[r+1]-=num;
}
那么最后需要查询了,就这样处理一下:

for (int i=1;i<=n;i++)
a[i]=a[i-1]+A[i];
那么就是原来的数组了.

时间复杂度O(1)修改,O(n)查询.

差分就是将数列中的每一项分别与前一项数做差,例如:

一个序列1 2 5 4 7 3,差分后得到1 1 3 -1 3 -4 -3

这里注意得到的差分序列第一个数和原来的第一个数一样(相当于第一个数减0)

差分序列最后比原序列多一个数(相当于0减最后一个数)

性质:

1、差分序列求前缀和可得原序列

2、将原序列区间[L,R]中的元素全部+1,可以转化操作为差分序列L处+1,R+1处-1

3、按照性质2得到,每次修改原序列一个区间+1,那么每次差分序列修改处增加的和减少的相同

public class Main {
//前缀和
public static void fun(int arr[],int A[]){
/*
A[1]=a[1] A[2]=a[1]+a[2] A[3]=a[1]+a[2]+a[3] A[4]=a[1]+a[2]+a[3]+a[4]
*/
for (int i=1;i<arr.length;i++)
A[i]=A[i-1]+arr[i]; }
public static int query(int l,int r,int A[]){
//查询区间[l,r]的时候只要输出A[r]-A[l-1]
return A[r]-A[l-1];
}
//差分
public static void fun2(int arr[],int A[]){
for (int i=1;i<arr.length;i++)
A[i]=arr[i]-arr[i-1];
}
public static void add(int l,int r,int num,int A[],int arr[]){
A[l]+=num;A[r+1]-=num;
for (int i=1;i<A.length;i++)
arr[i]=arr[i-1]+A[i];
} public static void main(String[] args) {
int arr[]={0,1,2,3,4};
int A[]=new int[5];
// fun(arr, A);
// System.out.println(query(1, 3, A));
// System.out.println(query(2, 4, A)); fun2(arr, A);
add(1, 3, 9, A, arr);
for (int i = 1; i < arr.length; i++) {
System.out.println(arr[i]);
}
} }

IncDec sequence 题解

对于一个给定的数列arr,它的差分数列A定义为, A[1]=arr[1],A[i]=arr[i]−arr[i−1](2<=i<=n) 即:A[1]=arr[1],A[i]=arr[i]−arr[i−1](2<=i<=n)

性质,把序列arr的区间[L,R]加d,也就是把arr[l],arr[l+1]........arr[r]都加上d,其实就是它的差分序列B中,A[l]+d,A[r+1]−d其他的位置统统不改变。
因此在这道题目中,我们就可以利用这个性质,因为我们只要求arr序列中所有的数相同,而不在意这些方案具体是什么,所以说我们就可以转化题目,也就是将对arr序列的+1,−1+1,−1操作,让arr序列相同,改成目标把A2,…,An变成全0即可(因为A[1]=arr[1],所以是A2~A[n]变成0),也就是arr序列全部相等。而且最后得到的arr序列,就是这n个A1
因为我们有上面所说的性质,那么我们就可以,每一次选取Ai和Aj,2<=i,j<=n而且这两个数,一个为正数,一个为负数,至于为什么要是正负配对,因为我们是要这个A序列2~n都要为0,所以这样负数增加,正数减少,就可以最快地到达目标为0的状态。
至于那些无法配对的数Ak可以选A1,进行修改。即Ak+d,A1-k,A1不影响全局操作
所以说我们这道题目得出的答案就是,最少操作数 min(p,q)+abs(p−q),然后最终序列a可能会有abs(p−q)+1种情况。p为b序列中正数之和,而q为b序列中负数之和

package 差分与前缀和;

import java.util.Scanner;

public class Main1 {
public static void fun2(long arr[],long A[]){
for (int i=1;i<arr.length;i++)
A[i]=arr[i]-arr[i-1];
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
long arr[]=new long[n+1];
for (int i = 1; i < arr.length; i++) {
arr[i]=sc.nextLong();
}
long A[]=new long[n+1];
fun2(arr, A);
long positiveNumber=0;
long negativeNumber=0;
for (int i = 2; i < A.length; i++) {
if (A[i]>=0) {
positiveNumber+=A[i];
}else{
negativeNumber-=A[i];
}
}
System.out.println(Math.abs(positiveNumber-negativeNumber)+Math.min(negativeNumber, positiveNumber));
System.out.println(Math.abs(positiveNumber-negativeNumber)+1);
} }

前缀和与差分之IncDec sequence的更多相关文章

  1. 【BZOJ 3043】 3043: IncDec Sequence (差分)

    3043: IncDec Sequence Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 589  Solved: 332 Description 给 ...

  2. bzoj 3043: IncDec Sequence 模拟

    3043: IncDec Sequence Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 248  Solved: 139[Submit][Statu ...

  3. Poetize6: IncDec Sequence

    3043: IncDec Sequence Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 233  Solved: 132[Submit][Statu ...

  4. 【BZOJ3043】IncDec Sequence 乱搞

    [BZOJ3043]IncDec Sequence Description 给定一个长度为n的数列{a1,a2...an},每次可以选择一个区间[l,r],使这个区间内的数都加一或者都减一.问至少需要 ...

  5. BZOJ 3043: IncDec Sequence

    3043: IncDec Sequence Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 578  Solved: 325[Submit][Statu ...

  6. 2498 IncDec Sequence

    2498 IncDec Sequence  时间限制: 1 s  空间限制: 64000 KB  题目等级 : 钻石 Diamond 题解  查看运行结果     题目描述 Description 给 ...

  7. CH-0304 IncDec Sequence

    0304 IncDec Sequence 0x00「基本算法」例题 描述 给定一个长度为 n(n≤10^5 ) 的数列 {a_1,a_2,…,a_n},每次可以选择一个区间 [l,r],使下标在这个区 ...

  8. 差分:IncDec Sequence 差分数组

    突然就提到了这个东西,为了不再出现和去年联赛看见二分没学二分痛拿二等第一的情况,就去学了一下,基础还是比较简单的-- 先看一个经典例题: 给定一个长度为n的数列{a1,a2...an},每次可以选择一 ...

  9. IncDec Sequence(差分)

    题意:给定一个序列,可以对一个区间进行加1或减1的操作,问最少需要多少次可以将序列的值一样. Solution 我们将序列差分,得到一个差分数组. 对于每一个区间操作,我们可以把它转化为在查分数组上某 ...

随机推荐

  1. sqli-labs(七)——登陆处sql注入

    第十三关: 这关也是一个登陆口,和上关所说的一样,先使用'"试一下,让程序报错然后判断后台的sql语句 可以看到后台sql大概是 where name = ('$name')...  这样的 ...

  2. LeetCode108.将有序数组转换为二叉搜索树

    将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. 示例: 给定有序数组: [-10,-3,0, ...

  3. c# 类一般在哪里实例化,是在类内、方法内还是其他地方?

    根据情况,你要一个页面内全局的就在类与方法之间实例化,如果一个方法需要使用这个类的对象,就在内部实例化

  4. laravel架构

    1.Laravel 5.1 中的异常处理器和HTTP异常处理实例教程 http://laravelacademy.org/post/1867.html 2.laravel 集成sentry,sentr ...

  5. gispro试用版账户注册

    1.注册账户 http://www.esri.com/zh-cn/arcgis/products/arcgis-pro/trial 2.分配账户权限 3.gispro可以登录了

  6. Nginx技术研究系列3-OpenResty安装配置

    上两篇中介绍了: Ngnix技术研究系列1-通过应用场景看Nginx的反向代理 Ngnix技术研究系列2-基于Redis实现动态路由 发现,应该加一篇OpenResty的安装部署说明,方便大家按图索骥 ...

  7. python字典的排序,按key排序和按value排序---sorted()

    >>> d{'a': 5, 'c': 3, 'b': 4} >>> d.items()[('a', 5), ('c', 3), ('b', 4)] 字典的元素是成键 ...

  8. php获取字符串长度函数strlen和mb_strlen

    php获取字符串长度函数strlen和mb_strlencount() - 计算数组中的单元数目,或对象中的属性个数strlen — 获取字符串长度,一个汉字为3个字符mb_strlen() - 获取 ...

  9. linux 环境RPM 安装MYSQL5.6

    linux 环境RPM 安装MYSQL5.6 系统环境 CentOS7.2 1.关闭selinux 服务[SELinux是一种基于域-类型 模型(domain-type)的强制访问控制(MAC)安全系 ...

  10. Java 线程类的一些常用方法

    线程类的一些常用方法: sleep(): 强迫一个线程睡眠N毫秒.  isAlive(): 判断一个线程是否存活.  join(): 等待线程终止.  activeCount(): 程序中活跃的线程数 ...