SKYLINE UVALive - 4108
生活随笔
收集整理的這篇文章主要介紹了
SKYLINE UVALive - 4108
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
我一開始沒有想到用線段樹,是我學得太僵了...
我們要記錄每段的最大高度,而且要組織成區間信息,這要用到線段樹
?
怎么用呢?
線段樹維護區間最大值;對于每個線段,先二分至其包含區間,如果最大值>=h,就能把這個區間賦值
優化:如果最小值<=h,即可返回
?
這道題算是一個線段樹的小魔改吧...
我們發現:對于線段樹,查詢和修改兩個操作是可以合在一起的;找區間也不是固定的,可以根據區間信息,二分至我們目標的區間
#include<iostream> #include<cstdio> #include<cstring>using namespace std;const int N=1e5+3,V=1e5+3;struct line{int l,r,h; }a[N];struct sgt{int mn,mx;int st; }R[V<<2];int gl; void push_down(int o,int l,int r){if(R[o].st){R[o<<1].mx=R[o<<1|1].mx=R[o<<1].mn=R[o<<1|1].mn=R[o].st;R[o<<1].st=R[o<<1|1].st=R[o].st;R[o].st=0;} } void push_up(int o,int l,int r){R[o].mx=max(R[o<<1].mx,R[o<<1|1].mx);R[o].mn=min(R[o<<1].mn,R[o<<1|1].mn); } int modify(int o,int l,int r) {if(a[gl].l<=l&&a[gl].r>=r){if(R[o].mx<=a[gl].h){R[o].mx=R[o].mn=a[gl].h;R[o].st=a[gl].h;return r-l+1;}else if(R[o].mn>a[gl].h)return 0; }push_down(o,l,r);int mid=(l+r)>>1,ret=0;if(a[gl].l<=mid)ret+=modify(o<<1,l,mid);if(a[gl].r>mid)ret+=modify(o<<1|1,mid+1,r);push_up(o,l,r);return ret; }int main() {int T;scanf("%d",&T);while(T--){int n;scanf("%d",&n);int bd=0;for(int i=1;i<=n;i++)scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].h),a[i].r--,bd=max(bd,a[i].r);int ans=0;memset(R,0,sizeof R);for(int i=1;i<=n;i++){gl=i;ans+=modify(1,1,bd);}printf("%d\n",ans);}return 0; }?
轉載于:https://www.cnblogs.com/mgnfcnt/p/9464389.html
總結
以上是生活随笔為你收集整理的SKYLINE UVALive - 4108的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分享股票量化交易程序化模型的设计思路
- 下一篇: java证明ArrayList是线程不安