• 差分【bzoj3043】IncDec Sequence


    Description

    给定一个长度为n的数列{a1,a2...an},每次可以选择一个区间[l,r],使这个区间内的数都加一或者都减一。 问至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列有多少种。

    Input

    第一行一个正整数n 。

    接下来n行,每行一个整数,第i+1行的整数表示ai。

    Output

    第一行输出最少操作次数。

    第二行输出最终能得到多少种结果。

    表示看到题很懵逼啊 emm

    解释感觉不是很对,希望大佬能指出错误 qwq

    这个是差分应该不难看出。

    我们首先处理出差分数组。

    想要我们的数列中的数相同,那么我们必须要保证差分数组中(2-n)全部都是(0)

    那么现在我们的问题就变成了,如何使用最小的步数使得差分数组中(2-n)部分全部为(0)

    我们用(s1)记录差分数组中所有正数的和.(s2)记录差分数组中所有负数的和。

    此时,正负可消

    什么是正负可消?

    我们将区间内的数加(1)与将区间内的数减(1)等效。

    所以对(s1,s2)(max)即为第一问答案。

    此时会有剩余部分,我们可以考虑对其单点修改,或者连同(1)到这个点修改。

    那么我们的答案就是两部分的中间的数的数量(包括两端)

    即为(|s1-s2|+1)

    代码

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #define R register
    #define lo long long 
    
    using namespace std;
    
    inline void in(R int &x)
    {
    	R int f=1;x=0;char s=getchar();
    	while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
    	while(isdigit(s)){x=x*10+s-'0';s=getchar();}
    	x*=f;
    }
    
    int n,last,x;
    lo s1,s2;
    
    int main()
    {
    	in(n);in(last);
    	for(R int i=2;i<=n;i++)
    	{
    		in(x);
    		if(x-last>0)s1+=x-last;
    		else s2+=(last-x);
    		last=x;
    	}
    	printf("%lld
    %lld",max(s1,s2),abs(s1-s2)+1);
    }
    
  • 相关阅读:
    MySQL事务_transaction
    mysql
    反射跳过泛型检查
    spring java.io.FileNotFoundException cannot be opened because it does not exist
    Servlet中ServletConfig的作用
    Exception in thread "main" java.lang.ClassCastException: java.base/java.util.HashMap$Values cannot be cast to java.base/java.util.ArrayList
    java中字符串和其他数据类型之间使用“+”号连接
    comboBox加载数据
    自动填充
    3号随笔,搭建web环境
  • 原文地址:https://www.cnblogs.com/-guz/p/9915801.html
Copyright © 2020-2023  润新知