2010山东省信息学夏令营模拟赛Test 5.浇水 题解

来源:互联网 发布:centos配置桥接模式 编辑:程序博客网 时间:2024/05/01 12:28

浇水 (water.c/cpp/pas)

【题目描述】

LazyChild在青岛二中科技楼里种了一排n棵树,每棵树都有一个高度。他会枚举所有的区间,然后从区间中找出一个高度最矮的树进行浇水(照顾弱者)。由于LazyChild浇完水之后就精疲力竭了,所以请你帮助他计算每棵树都被浇了几次水。

【输入文件】

第一行一个整数n。

第二行n个整数,分别表示每棵树的高度。

【输出文件】

一行n个整数用空格隔开,分别表示每棵树被浇了几次水。

【样例输入】

3

1 3 5

【样例输出】

3 2 1

【样例解释】

LazyChild枚举到了6个区间分别是[1],[3], [5], [1 3], [3 5], [1 3 5],对应的最矮的树的高度是1, 3, 5, 1, 3, 1。

【数据规模和约定】

对于40%的数据,n <= 1000

对于100%的数据,n <= 1000000,保证每棵树的高度都不相同


#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <stack>using namespace std;const int MaxLen = 1000000+2;int N;int tree[MaxLen], Left[MaxLen], Right[MaxLen];long long ans[MaxLen];stack<int>st;int main() {freopen("water1.in", "r", stdin); freopen("water1.out", "w", stdout);scanf("%d", &N);                  for(int i = 1; i<=N; ++i) scanf("%d", tree+i);                              //input;st.push(0);                                                                 //initialize_Left;for(int i = 1; i<=N; ++i){while(tree[st.top()]>tree[i]) st.pop();Left[i] = st.top();st.push(i);}                                                                           //cnt_Left;while(!st.empty()) st.pop();                                                //clean;st.push(N+1);                                                               //initialize_Right;for(int i = N; i; --i){while(tree[st.top()]>tree[i]) st.pop();Right[i] = st.top();st.push(i);}                                                                           //cnt_Right;for(int i = 1; i<=N; ++i) ans[i] = (long long)(i-Left[i])*(Right[i]-i);     //cnt;for(int i = 1; i<=N; ++i) printf("%lld%c", ans[i], (i==N?'\n':' '));        //output;fclose(stdin); fclose(stdout); return 0;}


原创粉丝点击