[線段樹-模板] 線段樹+離散化

輸入

每一個測試點(輸入文件)有且僅有一組測試數據。node

每組測試數據的第1行爲兩個整數N和L,分別表示總共貼上的海報數量和宣傳欄的寬度。ios

每組測試數據的第2-N+1行,按照貼上去的前後順序,每行描述一張海報,其中第i+1行爲兩個整數a_i, b_i,表示第i張海報所貼的區間爲[a_i, b_i]。測試

對於100%的數據,知足N<=10^5,L<=10^9,0<=a_i&ltb_i<=L。ui

輸出

對於每組測試數據,輸出一個整數Ans,表示總共有多少張海報能被看到。spa

 

#include <iostream> #include <cstring> #include <vector> #include <algorithm>
using namespace std; struct node{ int flag; // 海報編號 
    int l,r;  //左端點,右端點 
}; vector<int> v; //用於離散化 
int pt_x[100005],pt_y[100005];  //記錄區間端點
node tree[100000*40];  //線段樹
bool use[100005*2+10];  //記錄能看到的海報
int ans;  //能看到的海報數 //得到離散值
int getID(int x){ return lower_bound(v.begin(),v.end(),x)-v.begin()+1; } //建樹 
void build(int root,int l,int r){ tree[root].flag = 0; tree[root].l = l; tree[root].r = r; if(l+1==r)    return;  //到達葉子結點
    int mid = (l+r)/2; build(root*2,l,mid); build(root*2+1,mid,r); } void update(int l,int r,int root,int x){ if(tree[root].l==l&&tree[root].r==r){ tree[root].flag = x; return; } if(tree[root].l+1>=tree[root].r) return;  //到達葉子結點
    if(tree[root].flag){  //若是當前區間貼上了海報,其子區間也要更新 
        tree[root*2+1].flag = tree[root*2].flag = tree[root].flag; tree[root].flag = 0; } int mid = (tree[root].l+tree[root].r)/2; if(l>mid)  //待更新區間在當前區間的左半邊 
        update(l,r,root*2+1,x); else if(r<=mid)  //待更新區間在當前區間的右半邊 
        update(l,r,root*2,x); else{ //         update(l,mid,root*2,x); update(mid,r,root*2+1,x); } } void query(int root){ if(tree[root].flag&&!use[tree[root].flag]){ ans++; use[tree[root].flag] = 1; return; } if(tree[root].l+1>=tree[root].r) return;  //到達葉子結點
    if(!use[tree[root].flag]){ query(root*2); query(root*2+1); } } int main(int argc, char** argv) { int n,L; v.clear(); memset(tree,0,sizeof(tree)); scanf("%d %d",&n,&L); for(int i=0;i<n;i++){ scanf("%d %d",&pt_x[i],&pt_y[i]); v.push_back(pt_x[i]); v.push_back(pt_y[i]); } sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end()); int N = v.size(); build(1,1,N); for(int i=0;i<n;i++){ update(getID(pt_x[i]),getID(pt_y[i]),1,i+1); } ans = 0; memset(use,0,sizeof(use)); query(1); printf("%d\n",ans); return 0; }
相關文章
相關標籤/搜索