POJ2528 计算可见线段(线段树)
生活随笔
收集整理的這篇文章主要介紹了
POJ2528 计算可见线段(线段树)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
原題鏈接:POJ2528
解析:這題考察的是線段樹子區間更新的維護中的計算可見線段。
用離散化,排序去重,但是這題廣告是一塊瓷磚一塊瓷磚貼的,也就是說有可能離散化之后,明明倆個相鄰點之前有空白,但是由于離散化分配序號是緊挨著的,就造成了倆塊有廣告瓷磚緊挨。舉個例子,比如四號瓷磚(以下用號簡稱)和五號都有廣告,那么離散化之后四號序號為1,五號為2,他們之間沒別的位置,故全覆蓋,那如果四號和六號有廣告,但是五號沒有,由于我們離散化記錄的是廣告左右邊,故四號為1,六號為2,那么他們之間還是沒空白,這就與題意不符了。所以當相鄰邊大于1時,序號要多+1。
代碼實例:
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int maxn = 10100; int x[4*maxn]; int id[10000010]; struct CPost{int l,r;bool vis; }poster[maxn]; struct CNode{int l,r;bool bCovered;int Mid(){return (l+r)/2;} }tree[1000000]; void BuildTree(int root,int l,int r){tree[root].l = l;tree[root].r = r;tree[root].bCovered = false;if(l == r) return;BuildTree(2*root+1,l,(l+r)/2);BuildTree(2*root+2,(l+r)/2+1,r); } bool Push(int root,int s,int e){if(tree[root].bCovered) return false;if(s == tree[root].l && e == tree[root].r){tree[root].bCovered = true;return true;}bool res;if(e <= tree[root].Mid()) res = Push(2*root+1,s,e);else if(s > tree[root].Mid()) res = Push(2*root+2,s,e);else{bool r1 = Push(2*root+1,s,tree[root].Mid());bool r2 = Push(2*root+2,tree[root].Mid()+1,e);res = r1 || r2;}if(tree[2*root+1].bCovered && tree[2*root+2].bCovered)tree[root].bCovered = true;return res; }int main() {int t;scanf("%d",&t);while(t--){int n,cnt;scanf("%d",&n);for(int i = 0;i < n;i++){scanf("%d%d",&x[i],&x[i+n]);poster[i].l = x[i];poster[i].r = x[i+n];}sort(x,x+2*n);cnt = unique(x,x+2*n)-x;int interval = 1;for(int i = 0;i < cnt;i++){id[x[i]] = interval;if(i < cnt-1){if(x[i+1] - x[i] == 1) interval++;else interval += 2;}}BuildTree(0,1,interval);int ans = 0;for(int i = n-1;i >= 0;i--){int s = id[poster[i].l];int e = id[poster[i].r];if(Push(0,s,e)) ans++;}printf("%d\n",ans);} return 0; }?
轉載于:https://www.cnblogs.com/long98/p/10352196.html
總結
以上是生活随笔為你收集整理的POJ2528 计算可见线段(线段树)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ProxySQL 故障
- 下一篇: django celery