2016 Multi-University Training Contest 10 [HDU 5861] Road (线段树:区间覆盖+单点最大小)...
生活随笔
收集整理的這篇文章主要介紹了
2016 Multi-University Training Contest 10 [HDU 5861] Road (线段树:区间覆盖+单点最大小)...
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
HDU 5861
題意
在n個村莊之間存在n-1段路,令某段路開放一天需要交納wi的費用,但是每段路只能開放一次,一旦關閉將不再開放?,F在給你接下來m天內的計劃,在第i天,需要對村莊ai到村莊bi的道路進行開放。在滿足m天內花費最小的情況下,求出每天的花銷。
?
分析:
我們可以想到用線段樹想到記錄每一段路的開始時間與結束時間,開始時間很簡單,就是一開始的時間,結束的時間求法可以參考區間覆蓋,這是類似的;
然后我們在轉化哪一天開哪些,哪一天關哪些,那這天的貢獻sum = 開-關 ;
?
這很關鍵,我在比賽就沒有想出來。。? ?
例:如st[1]=3,表示第1段道路的最早開始時間是第3天,那么你可以start[3].push_back(1),表示第3天開啟第1段道路,這樣掃一遍過去就行了;
這是一種,要不就用d[be[i]]+=w[i] , d[en[i]]-=w[i];? 其實差不多
?
#include<bits/stdc++.h>using namespace std ; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int maxn = 200020; int Begin[maxn << 2], End[maxn << 2]; int be[maxn],en[maxn],w[maxn]; long long sum[maxn],d[maxn]; void pushdown(int rt)//向下跟新 {if(!Begin[rt<<1])Begin[rt<<1]=Begin[rt];if(!Begin[rt<<1|1])Begin[rt<<1|1]=Begin[rt];if(!End[rt])return ;End[rt<<1]=End[rt<<1|1]=End[rt];End[rt]=0;///優化用過了就可以不用了 } void build(int l , int r , int rt) {Begin[rt]=End[rt]=0;if(l==r)return ;int m = (l+r) >> 1 ;build(lson);build(rson); }void update(int L , int R , int k , int l , int r , int rt) {if(L<=l && r<=R){if(!Begin[rt])///很簡單的道理,我跟新過了就不跟新了;Begin[rt]=k;End[rt]=k;return ;}pushdown(rt);int m=(l+r) >> 1;if(m>=L)update(L,R,k,lson);if(m<R)update(L,R,k,rson); } void pushall(int l , int r , int rt) {if(l==r){be[l]=Begin[rt],en[l]=End[rt];return ;}pushdown(rt);int m=(l+r)>>1;pushall(lson);pushall(rson); } int main() {int n,m;while(~scanf("%d%d",&n,&m)){n--;build(1,n,1);///建樹for(int i=1 ; i<=n ; i++)scanf("%d",&w[i]);for(int i=1 ; i<=m ; i++){int u,v;scanf("%d%d",&u,&v);if(u>v)//防止意外 swap(u,v);update(u,v-1,i,1,n,1);///u到v區間更新為i(天); }pushall(1,n,1);//找到每一段路的開始時間與結束時間memset(d,0,sizeof(d));for(int i=1 ; i<=n ; i++)//每一段路的開始費用與結束費用 {if(be[i]){d[be[i]]+=w[i];d[en[i]+1]-=w[i];}}sum[0]=0;for(int i=1 ; i<=m ; i++)///類似與掃描線,一天一天的掃過去 {sum[i]=sum[i-1]+d[i];printf("%lld\n",sum[i]);}} } View Code?
線段樹真厲害,以后就不要只是固定與模板,要與線段樹的結構與自己需要用的功能結合
轉載于:https://www.cnblogs.com/shuaihui520/p/9795013.html
總結
以上是生活随笔為你收集整理的2016 Multi-University Training Contest 10 [HDU 5861] Road (线段树:区间覆盖+单点最大小)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 洛谷 P1028 数的计算
- 下一篇: Laravel POST请求API接口