(找到最小 ) CD

来源:互联网 发布:在手机上淘宝评价管理 编辑:程序博客网 时间:2024/06/05 06:35

题意 :给一片楼照相,现在然后把照片剪成N片,

          第i片中的楼高度为,,求出相片中最少的楼的数目。


思路:用线段树维持一段中的最小高度。

            建好树后,对数入的数和其ID同时排序,并把相同高度的ID也是由小到大的排序。

            从开始遍历,如果是相邻两段的高度相同并且其之间段的最小高度都大等于其高度,则认为他们是同一个楼的。


#include<iostream>#include<cstdio>#include<algorithm>using namespace std;#define N 100100int n,q;struct car{int high,i;}go[N];struct my{int left,right;int mid;int   small;int  temp;}t[N*4];void build(int cur,int l,int r){t[cur].left=l;t[cur].right=r;t[cur].temp=0;t[cur].small=0;t[cur].mid=(l+r)>>1;if (l!=r){build(cur<<1,l,t[cur].mid);build(cur<<1|1,t[cur].mid+1,r);t[cur].small=min(t[cur<<1].small,t[cur<<1|1].small);}else{t[cur].small=go[l].high;}}void update(int cur,int l,int r,int  v){if (l==t[cur].left && r==t[cur].right){t[cur].small+=v;t[cur].temp+=v;return;}int L=cur<<1,R=cur<<1|1;if (t[cur].temp){t[L].temp+=t[cur].temp;t[R].temp+=t[cur].temp;t[L].small+=t[cur].temp;t[R].small+=t[cur].temp;t[cur].temp=0;}if (r<=t[cur].mid)update(L,l,r,v);else if (l>t[cur].mid)update(R,l,r,v);else {update(L,l,t[cur].mid,v);update(R,t[cur].mid+1,r,v);}t[cur].small=min(t[L].small,t[R].small);}int  find(int cur,int l,int r){//cout<<cur<<' '<<l<<' '<<r<<' '<<t[cur].left<<' '<<t[cur].right<<' '<<t[cur].big<<endl;if (l==t[cur].left && r==t[cur].right){return t[cur].small;}int L=cur<<1,R=cur<<1|1;if (t[cur].temp){t[L].temp+=t[cur].temp;t[R].temp+=t[cur].temp;t[L].small+=t[cur].temp;t[R].small+=t[cur].temp;t[cur].temp=0;}int ans=0;if (r<=t[cur].mid)ans=find(L,l,r);else if (l>t[cur].mid)ans=find(R,l,r);else ans=min(find(L,l,t[cur].mid),find(R,t[cur].mid+1,r));t[cur].small=min(t[L].small,t[R].small);return ans;}bool cmp(car a,car b){if (a.high!=b.high)return a.high<b.high;return a.i<b.i;}int main(){freopen("in.txt","r",stdin);int i,j,k;int num=1;while (cin>>n){for (i=1;i<=n;i++)scanf("%d",&go[i].high),go[i].i=i;build(1,1,n);sort(go+1,go+n+1,cmp);int ans=0;//cout<<find(1,2,5)<<endl;for (i=j=1;i<=n;i=j)  if (go[i].high){//cout<<i<<endl;j=i+1;ans++;while (j<=n && go[j].high==go[i].high && find(1,go[i].i,go[j].i)>=go[i].high) j++;}elsej++;cout<<"Case "<<num++<<": ";cout<<ans<<endl;}return 0;}



How Many Buildings

Time Limit: 1000 ms Memory Limit: 65535 kB Solved:41 Tried: 160

Submit

Status

Best Solution

Back

Description

Kenny在仰望星空,思考怎么拿奥斯卡奖的时候误入了一座奇怪的城市,他很兴奋地照了几张照片。结果当他把照片印出来才发现他根本数不清照片里有几座楼。于是他想了个办法来试着计算一发:

首先,他把照片竖着切成了n条,从左到右排成一排。照片里的楼房都可以看成是一个个矩形框,而照片的下边沿就是地面。一座楼房可能会在连续的好几条照片里面出现,但是每条照片里面显示的是该位置最高的楼房的高度,仅凭Kenny的钛合金眼是分辨不出这个位置到底重叠了几座楼的。

然后,他算出了每条照片里面可见楼房的高度。

最后,他要写个程序,求一求至少原图里有几座楼房。为了宇宙的和平,你来求一发吧。

Input

有多组测试数据,每组数据包括一个整数n(1 <= n <= 100,000),下一行有n个整数,也就是从左到右每条照片里楼的高度(0代表照片里没有楼房)。所有的输入数据均非负,小于1,000,000,000。

Output

每组Case,先输出Case数,然后输出答案。

Sample Input

3
1 2 3
3
1 2 1

Sample Output

Case 1: 3
Case 2: 2