[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;
}