[NOIp模拟赛][差分数组][栈] 区间

题面

有一个 \(n\) 个数的序列,一开始所有的数都是 \(0\),每次可以将一个区间 \([l,\ r](l \le r)\) 内的数 \(+1\),求到达最终状态的最少操作次数。

其实这个题的本质问题是枚举区间端点……

# include <iostream>
# include <cstdio>
# define MAXN 100005

int a[MAXN];
int ans[MAXN], cntA;

int main(){
	int n;
	scanf("%d", &n);

	for(int i = 1; i <= n; i++){
		scanf("%d", &a[i]);
	}

	for(int i = n+1; i >= 1; i--){ // 这样就不用单独开差分数组了
		a[i] -= a[i-1];
		while(a[i] < 0){ // 说明前面是一个比当前位置大的区间端点
		// 将这两个位置减到相同时就相当是把它们搞进同一个区间了
			ans[++cntA] = i-1; // ans 本质是个栈
			a[i]++;
		}
	}

	printf("%d\n", cntA);

	for(int i = 1; i <= n; i++){
		while(a[i] > 0){
			printf("%d %d\n", i, ans[cntA--]);
			a[i]--;
		}
	}

	return 0;
}
posted @ 2020-09-23 17:24  ChPu437  阅读(161)  评论(0编辑  收藏  举报