zoukankan      html  css  js  c++  java
  • P4552 [Poetize6] IncDec Sequence 题解

    原题链接

    简要题意:

    给定长度为 \(n\) 的序列 \(\{a_i\}\),每次操作可以将任一区间 \([l,r]\) 的所有数加一(或减一),求至少多少次操作可以让序列中所有数相同。并且在保证最小操作数的情况下求相同的数的可能个数(即末状态数)。

    \(n \leq 10^5\).

    区间操作往往可以转换为差分操作。

    注意到,如果我们令 \(\{c_i\}\)\(\{a_i\}\) 的差分数组,也就是:

    \[\begin{cases} c_1 = a_1 \\ c_k = a_k - a_{k-1} (\forall k \in [2,n]) \\ \end{cases}\]

    那么,这个时候,对于 \(\{a_i\}\) 中,\([l,r]\) 区间的 \(+1\) 操作,可以简化为:

    \[\begin{cases} c_{l} \leftarrow c_{l} + 1 \\ c_{r+1} \leftarrow c_{r+1} - 1 \\ \end{cases}\]

    同理 \(-1\) 操作可以简化为:

    \[\begin{cases} c_{l} \leftarrow c_{l} - 1 \\ c_{r+1} \leftarrow c_{r+1} + 1 \\ \end{cases}\]

    同时我们发现,\(\{a_i\}\) 全相等时,\(\{c_i\}\)\(c_1 = a_1\) 外全为 \(0\),于是题意转为:

    给定一个长度为 \(n\) 的序列 \(\{c_i\}\),每次操作可以选定任意的 \(l,r\) 并将 \(c_l\)\(c_r\) 一个加一,一个减一。求能使得 \(c_2 \cdots c_n\) 全部变为 \(0\) 的最少操作数,以及变化后 \(c_1\) 可能的值的个数。

    这里,答案已经呼之欲出了。

    很显然,我们应该尽量把一个负数 \(c_x\) 和一个正数 \(c_y\) 同时进行 “绝对值逼近 \(0\)” 的加减操作,通过 \(\min(c_x,c_y)\) 次可以得到 \(0\). 于是我们将所有正数的和记为 \(p\),负数的 绝对值 的和记为 \(q\),显然,想要消灭所有正数(或负数)需要 \(\min(p,q)\) 次。而对于剩下的数,我们可以将其和 \(c_1\) 进行加减操作。于是第一问答案为 \(\max(p,q)\),这是十分明显的。

    考虑第二问。注意到,需要满足最小操作数,因此 “绝对值逼近 \(0\)” 的加减操作 是不可能改变 \(c_1\) 的。但是注意到,最后对于剩下的数,当只剩下一个数 \(c_n \not = 0\) 的时候(注意一定是 \(n\)),我们就可以不一定选定 \([1,x]\) 操作。可以直接选定 \([n,n+1]\) 进行操作(想象你变化原数组末位的时候,后面一位的差分值也会变),而不是改变 \(c_1\). 也只有在这个时候才能在保证最小操作数的情况下使得 \(c_1\) 有更多可能性。此时 \(|c_n| = |p-q|\) 显然。

    于是第二问答案为 \(|p-q|+1\).

    时间复杂度:\(\mathcal{O}(n)\).

    代码实现中,差分利用滚动一波过去了。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=1e5+1;
    typedef long long ll;
    
    int n;
    ll p,q;
    
    int main() {
    	scanf("%d",&n);
    	int x; scanf("%d",&x);
    	for(int i=2;i<=n;i++) {
    		int y; scanf("%d",&y);
    		if(y>x) p+=y-x;
    		else q+=x-y;
    		x=y;
    	}
    	printf("%lld\n%lld\n",max(p,q),abs(p-q)+1);
    	return 0;
    }
    
    简易的代码胜过复杂的说教。
  • 相关阅读:
    npm ERR! code EINTEGRITY npm ERR! sha1- 报错解决办法
    create-react-app创建项目报错SyntaxError: Unexpected end of JSON input while parsing near '...ttachment":false,"tar' npm代理
    七大设计原则
    UML类图和时序图
    linux环境下排查cpu占比高的MySQL数据库sql语句
    Angular 2 imooc 学习笔记
    angular JS 学习笔记
    Hibernate HQL基础
    Hibernate注解
    Hibernate多对多映射
  • 原文地址:https://www.cnblogs.com/bifanwen/p/15733755.html
Copyright © 2011-2022 走看看