zoukankan      html  css  js  c++  java
  • 【】plusplus

    【链接】h在这里写链接


    【题意】


    给你一个长度为n的a数组.
    再给你一个相同长度的b数组,一开始全为0.
    给你m个操作,每个操作li,ri.
    表示把b数组的li..ri这一段的元素全都加上di.
    让你找最小的k(k>=0),使得第k次操作过后,b数组变成了a数组.
    (不存在就输出-1)
    n,m<=10^6,li,ri<=n,di<=10^9,a[i]<=10^18



    【题解】


    设c[i]表示a数组第i个位置与第i-1个位置的差。
    c[1] = a[1],c[2] = a[2]-a[1],c[3] = a[3]-a[2]....
    则这个c[i]数组,实际上表明的是,b数组,i这个位置比前一个位置要多加上的数字大小
    统计c数组不为0的个数cnt.
    显然,当cnt变成0了。则满足题目要求了。
    在把li..ri进行操作的时候,li+1..ri这个区间里面的c数组是不会发生改变的。因为它们是同增的.
    只需改变li和ri+1位置的c数组就好.
    然后改变cnt.
    直到cnt变成0就好.
    复杂度是O(N)的。

    【错的次数】


    0

    【反思】


    关键点就是构造出这个c数组。

    【代码】

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e6;
    
    int n, m;
    int a[N + 10];
    
    int main() {
    	scanf("%d%d", &n, &m);
    	for (int i = 1; i <= n; i++)
    		scanf("%d", &a[i]);
    	for (int i = n; i >= 1; i--)
    		a[i] = a[i] - a[i - 1];
    	int cnt = 0;
    	for (int i = 1; i <= n; i++)
    		if (a[i])
    			cnt++;
    	if (cnt == 0)
    		return puts("0"), 0;
    	for (int i = 1; i <= m; i++) {
    		int l, r, x;
    		scanf("%d%d%d", &l, &r, &x);
    		r++;
    		if (a[l] == 0 && a[l] - x != 0) cnt++;
    		if (a[l] != 0 && a[l] - x == 0) cnt--;
    		if (r <= n && a[r] == 0 && a[r] + x != 0) cnt++;
    		if (r <= n && a[r] != 0 && a[r] + x == 0) cnt--;
    		a[l] -= x, a[r] += x;
    		if (cnt == 0) {
    			printf("%d
    ", i);
    			return 0;
    		}
    	}
    	puts("-1");
    	return 0;
    }


  • 相关阅读:
    使用Xshell和Xftp部署简单的项目
    1-27 sed基本编程和cut基本应用
    1-26-1-expect无交互式-正则表达式
    1-24-case流程控制和while循环语句的使用
    1-23-shell脚本之-if流程控制语句和for循环语句的使用
    1-22-shell脚本基本应用-实验手册
    1-22-shell脚本的基础
    1-21 网络管理相关的命令
    总结 1-1 ~ 1-6
    windows系统下Eclipse启动界面更改
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626031.html
Copyright © 2011-2022 走看看