zoukankan      html  css  js  c++  java
  • [BZOJ3043]IncDec Sequence

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

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

    Output 第一行输出最少操作次数 第二行输出最终能得到多少种结果

    Sample Input 4 1 1 2 2

    Sample Output

    1 2

    HINT 对于100%的数据,n=100000,0<=ai<2147483648


    我们考虑把读入顺序作为第一关键字,权值作为第二关键字,在二维平面上描出一些折线

    如果我们要让所有的数变为v,则画一条y=v的线,并将坐标轴平移,使得x轴与那条直线重合,这样我们改值相当于将所有的折线上下平移

    那么对于某条折线图,答案为所有的峰值减去谷值。我们可以发现,[1,n]中峰值减去谷值是不变的,那么答案的改变就在于v[1]、v[n]与0的关系

    我们考虑,如果v[1]、v[n]相同,那么我们让数轴挪动到v[1]高度,即可让答案最优

    如果v[1]、v[n]不同,那么数轴在两个数之间挪动,答案不会改变;但让两个数都位于数轴的同侧后,答案一定会增加

    因此我们直接令v=v[1],求出第一问的答案,第二问答案即为|v[1]-v[n]|

    /*program from Wolfycz*/
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define inf 0x7f7f7f7f
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline char gc(){
    	static char buf[1000000],*p1=buf,*p2=buf;
    	return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int frd(){
    	int x=0,f=1; char ch=gc();
    	for (;ch<'0'||ch>'9';ch=gc())	if (ch=='-')	f=-1;
    	for (;ch>='0'&&ch<='9';ch=gc())	x=(x<<3)+(x<<1)+ch-'0';
    	return x*f;
    }
    inline int read(){
    	int x=0,f=1; char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')	f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<3)+(x<<1)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x<0)	putchar('-'),x=-x;
    	if (x>9)	print(x/10);
    	putchar(x%10+'0');
    }
    const int N=1e5;
    ll v[N+10],n,Ans,Last;
    int main(){
    	scanf("%lld",&n);
    	ll Ans=0,Last=0;
    	for (int i=1;i<=n;i++)	scanf("%lld",v+i);
    	for (int i=1;i<=n;i++){
    		ll tmp=v[i]-v[1];
    		if ((tmp<0)^(Last<0))	Last=0;
    		if (tmp>0)	Ans+=max(0ll,tmp-Last);
    		if (tmp<0)	Ans+=max(0ll,Last-tmp);
    		Last=tmp;
    	}
    	printf("%lld
    ",Ans);
    	printf("%lld
    ",abs(v[1]-v[n])+1);
    	return 0;
    }
    
  • 相关阅读:
    2020软件工程作业06
    2020软件工程作业05
    jdk13.0.2安装完成后,使用binjlink.exe 命令配置jre报错
    软件工程04(已报废)
    2020软件工程作业03
    软件工程问题解决清单
    软件工程作业02
    2020软件工程作业01
    2020软件工程个人作业06——软件工程实践总结作业
    2020软件工程作业05
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/10002459.html
Copyright © 2011-2022 走看看