題意:現在有n座橋,給出每個橋的高度,現在會發m次的洪水,每次洪水會漲至a高度,然後退回b的高度,問有多少橋至少被淹沒了k次。
題解:先吐槽一下:唉,人太蠢怎麼辦?連二分都沒有想到,其實這一題的key就是想到二分,想到二分去解決,那麼這一題就是模板題了。吐槽完畢
很明顯直接模擬會超時。
考慮使用二分,查詢高度在b[i-1],到a[i]高度的橋,即在大小在[a[i],b[i-1]]這個區間算一次淹沒,然後就是這個區間每個橋淹次數+1次,直接使用線段樹區間更新,複雜度m*logn
#include#include#include#include#include#include#include#includeusing namespace std;
#define inf 0x3f3f3f3f
#define n 100005
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
int arr1[n];
struct point
tree[n<<2];
int num=0;
void pushdown(int rt,int leg)
} void build(int l,int r,int rt)
int mid=(l+r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
} void update(int l,int r,int c,int rt)
pushdown(rt,tree[rt].rc-tree[rt].lc+1);
int mid=(tree[rt].rc+tree[rt].lc)>>1;
if(r<=mid)update(l,r,c,rt<<1);
else if(l>mid)update(l,r,c,rt<<1|1);
else
} void query(int l,int r,int rt)
pushdown(rt,tree[rt].rc-tree[rt].lc+1);
int mid=(tree[rt].lc+tree[rt].rc)>>1;
if(r<=mid)
else if(l>mid)
query(l,r,rt<<1|1);
else
} int main()
sort(arr1+1,arr1+n+1);
while(m--)
printf("case %d: %d\n",++cas,ans);
} return 0;
}
UVA 12663 水淹橋(二分)
最近下了很大的雨,小p都不能開心的出去玩耍了。所以無聊的小p找事來了。在這些天總共下了很多次雨,每次下雨後,河的水位都會上公升一些,然後雨過後水位又會下降到一定位置。在這個河上有許多橋,小p想知道在這些雨過後,有多少橋被淹沒不少於k次。如果橋的位置高於當前水位,洪水來後,水位 將橋淹沒 水位與橋同等...
Sequence(線段樹 二分)
傳送門 第二次做這種題目,把人做傻了,沒想到是二分,只是隱隱約約感覺到了二分的影子。於是寫了兩個查詢的函式,但是發現查詢的函式無法解決求左邊最大值和右邊最小值的問題。寫了一大堆爛 正解只需要在查詢的時候不斷二分就行了。include using namespace std typedef long ...
VVQ 與線段 線段樹 二分
原題鏈結 這題主要是要去判斷2個線段會不會又交集。首先將線段按r從小到大排列,然後乙個乙個放進線段樹裡面方便以後查詢有交集的範圍內的被減數的最小值。然後求交集,若lr與lr有交集,且r是右邊的那個線段。就有l r r,這裡可以使用二分函式lower bound求,主要快一點。然後,交集又分2種情況。...