近來a國和b國的矛盾激化,為了預防不測,a國準備修建一條長長的防線,當然修建防線的話,肯定要把需要保護的城市修在防線內部了。可是a國上層現在還猶豫不決,到底該把哪些城市作為保護物件呢?又由於a國的經費有限,所以希望你能幫忙完成如下的乙個任務:
給出你所有的a國城市座標
a國上層經過討論,考慮到經濟問題,決定取消對i城市的保護,也就是說i城市不需要在防線內了
a國上層詢問對於剩下要保護的城市,修建防線的總經費最少是多少
你需要對每次詢問作出回答。注意單位1長度的防線花費為1。
a國的地形是這樣的,形如下圖,x軸是一條河流,相當於一條天然防線,不需要你再修建
a國總是有兩個城市在河邊,乙個點是(0,0),乙個點是(n,0),其餘所有點的橫座標均大於0小於n,縱座標均大於0。a國有乙個不在(0,0)和(n,0)的首都。(0,0),(n,0)和首都這三個城市是一定需要保護的。
資料範圍:
30%的資料m<=1000,q<=1000
100%的資料m<=100000,q<=200000,n>1
所有點的座標範圍均在10000以內, 資料保證沒有重點
要動態維護乙個凸包。還要維護刪除操作?
刪除麻煩,可以離線,把刪除變成插入操作。
一切就簡單又自然了。
插入乙個點t,就要找到凸包上的第乙個大於等於橫座標x的點p,和第乙個小於x的點q。即後繼前驅。
題目很善良,河邊點不會刪除,所以一定在凸包上,不會有什麼邊界的鍋。
如果在凸包裡面那麼就直接返回,怎麼判斷?
如果q和p的斜率在t和p的斜率,t和q的斜率大小之間的話,那麼這個點一定不在凸包上。畫圖可以理解。
反之就一定在凸包上。
然後開始彈出點。不斷向右比較斜率,再不斷向左比較斜率。
最後把t加入凸包。
刪除點的時候,實時更新防線的長度。
不要忘了最後把p、q之間的連邊刪除。
找前驅後繼再刪除,可以用splay實現。
但是沒有必要,set完全可以支援。
**:
#includeusingnamespace
std;
const
int n=100000+10
;const
double inf=19260817.0
;int
n,m;
intcx,cy,far;
double
now;
struct
queq[
2*n];
struct
po
void
op()
}a[n];
bool
die[n];
sets;
set::iterator it1,it2,it3;
double
dis(po a,po b)
double slo(po a,po b)
return ((double)a.y-(double)b.y)/((double)a.x-(double
)b.x);
}void
upda(po lp)
now-=dis(*it1,*it2);
it3=it2;it3++;
while(it3!=s.end()&&slo(lp,*it2)<=slo(lp,*it3))
now+=dis(lp,*it2);
it3=it1;it3--;
while(it1!=s.begin()&&slo(lp,*it1)>=slo(lp,*it3))
now+=dis(lp,*it1);
s.insert(lp);
}int
main()
scanf("%d
",&m);
for(int i=1;i<=m;i++)
po st;st.x=0,st.y=0
;s.insert(st);
po nd;nd.x=far,nd.y=0
;s.insert(nd);
po ca;ca.x=cx,ca.y=cy;s.insert(ca);
now=dis(st,ca)+dis(ca,nd);
for(int i=1;i<=n;i++)
}for(int i=m;i>=1;i--)
else
}for(int i=1;i<=m;i++)
}return0;
}
總結:現在我們有了一些斜率優化中,維護凸包的方法。
1.單調佇列,適用於斜率有單調性,並且x要有單調性。才可以直接隊頭彈出,隊尾插入。均攤o(1)
2.佇列+二分。對於加入點的x有單調性,但是查詢的斜率無單調性的時候,就要二分了。
二分到第乙個斜率大於/小於查詢斜率的點,作為決策點即可。除了隊尾加入的時候,為了維護凸包所需,不會從隊頭彈出點。】
3.set(平衡樹)維護。對於一般情況的凸包,可能加入的x在任何位置,查詢什麼凸包的周長,就必須用set了。
但是,對於斜率優化中,要查詢乙個第乙個和後繼/前驅比k大/小的點,因為set是按照x過載的運算子,不能直接lower_bound了。
所以,只能手寫一棵splay,(就我所知)別無他法。
具體來說,乙個splay樹上的節點,按照x排序,而且必須還要記錄和後繼的斜率slope,和子樹內所有後繼斜率slope的最小值,便於直接二分。
HAOI2011 防線修建
傳送門 參考部落格 練習s tl stlst l庫。動態維護凸包。由於題目要求乙個乙個刪除,可以考慮反過來離線操作,乙個乙個加回去。當新增加乙個點的時候,往它的左右兩邊擴張 set setse t中按照x xx排好序 看是否需要修改凸包。用叉積判斷即可。注意最開始要加上dis 0,0 x,y dis...
HAOI2011 防線修建
洛谷鏈結 太懶了,懶得描述題面了。凸包刪點誰受得了,凸包就沒法維護了,所以我們倒著看,把刪點改為加點,每次加乙個可能導致一些點從凸包上消失,但每個點消失一次就回不來了,所以每個點訪問一次,可以保證複雜度。還好這題是個殼不是個包,否則比較毒瘤了。每次加入乙個點,首先需要考慮它是否在凸包中,如果在就 r...
HAOI2011 BZOJ2300 防線修建
description 近來a國和b國的矛盾激化,為了預防不測,a國準備修建一條長長的防線,當然修建防線的話,肯定要把需要保護的城市修在防線內部了。可是a國上層現在還猶豫不決,到底該把哪些城市作為保護物件呢?又由於a國的經費有限,所以希望你能幫忙完成如下的乙個任務 給出你所有的a國城市座標 a國上層...