zoukankan      html  css  js  c++  java
  • [差分] Jzoj P5812 区间

    Description

    每一个机房中总有一个红太阳。有一天,AmberFrame 来到机房,发现桌上有不知道哪个蒟蒻放上的问 题: 有一个 n 个数的序列,一开始所有的数都是 0,每次可以将一个区间 [l, r](l ≤ r) 内的数 +1,求到达最 终状态的最少操作次数。 AmberFrame 非常强,自然不会把时间花在这种水题上。因此他就把任务交给了你,如果不会做的话,他 可能就会觉得你就是那个放问题的蒟蒻了而把你批判一番了。 
     

    Input

    第一行包含一个正整数 n,表示序列的长度。
    第二行包含 n 个非负整数 a1, a2, ..., an,表示最终的状态。

    Output

    输出的第一行是一个正整数 m,表示最少的操作次数。 接下来 m 行每行两个正整数 li , ri,表示一次操作。你需要保证 1 ≤ li ≤ ri ≤ n。 保证最少次数 m ≤ 10^5,输出可以以任意顺序输出。 
     

    Sample Input

    6
    2 3 3 3 3 3

    Sample Output

    3
    1 6
    1 6
    2 6
     

    Data Constraint

     

    Hint

    下发样例中第 i 个样例与第 i 组数据范围相符。
    对于样例 1,第一个数被加了两次,其他每个数都被加了三次,显然满足条件。

    题解

    • 定义一个k,表示当前i的值
    • 那么每次比较a[i]与k
    • 如果a[i]>k,则打入a[i]-k个+1标记
    • 如果a[i]<k,则打入k-a[i]个-1标记,并且与+1标志匹配

    代码

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 using namespace std;
     6 int n,ans,z;
     7 int a[100005],l[100005],r[100005];
     8 int main()
     9 {
    10     freopen("range.in","r",stdin);
    11     freopen("range.out","w",stdout);
    12     scanf("%d",&n);
    13     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    14     int k=0;
    15     for(int i=1;i<=n+1;i++)
    16     {
    17         while(a[i]>k) k++,l[++ans]=i;
    18         while(a[i]<k) k--,r[++z]=i-1;
    19     }
    20     printf("%d
    ",ans);
    21     for(int i=1;i<=ans;i++) printf("%d %d
    ",l[i],r[i]);
    22     return 0;
    23 }
  • 相关阅读:
    6.66 分钟,一文Python爬虫解疑大全教入门!
    十分钟快速入门 Python,看完即会,不用收藏!
    Python3中真真假假True、False、None等含义详解
    Python基础系列讲解——时间模块详解大全之time模块
    超详细Pycharm部署项目视频教程
    Python进阶量化交易专栏场外篇7- 装饰器计算代码时间
    docker 基本命令
    Linux常用命令
    Docker-部署Mysql
    docker 容器内运行vim命令
  • 原文地址:https://www.cnblogs.com/Comfortable/p/9475246.html
Copyright © 2011-2022 走看看