1. 程式人生 > >5168. [HAOI2014]貼海報【線段樹】

5168. [HAOI2014]貼海報【線段樹】

stream sin int pushd def spa using byte ostream

Description

Bytetown城市要進行市長競選,所有的選民可以暢所欲言地對競選市長的候選人發表言論。為了統一管理,城市委 員 會為選民準備了一個張貼海報的electoral墻。張貼規則如下: 1.electoral墻是一個長度為N個單位的長方形,每個單位記為一個格子; 2.所有張貼的海報的高度必須與electoral墻的高度一致的; 3.每張海報以“A B”表示,即從第A個格子到第B個格子張貼海報; 4.後貼的海報可以覆蓋前面已貼的海報或部分海報。 現在請你判斷,張貼完所有海報後,在electoral墻上還可以看見多少張海報。

Input

第一行: N M 分別表示electoral墻的長度和海報個數 接下來M行: Ai Bi 表示每張海報張貼的位置

Output

輸出貼完所有海報後,在electoral墻上還可以看見的海報數。 1 0<= N <= 10000000 1<=M<=1000 1<= Ai <= Bi <=10000000 所有的數據都是整數。數據之間有一個空格

Sample Input

100 5
1 4
2 6
8 10
3 4
7 10

Sample Output

4 裸的線段樹區間覆蓋的題目,覆蓋一下最後統計一波就好了
 1 #include<iostream>
 2
#include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #define N (1000000+100) 6 using namespace std; 7 8 int Segt[N<<2]; 9 int n,m,x[N],y[N],id[N],cnt,num,ans; 10 bool vis[N]; 11 12 void Pushdown(int now) 13 { 14 if (Segt[now]) 15 { 16 Segt[now<<1
]=Segt[now]; 17 Segt[now<<1|1]=Segt[now]; 18 Segt[now]=0; 19 } 20 } 21 22 void Update(int now,int l,int r,int l1,int r1,int k) 23 { 24 if (l>r1 || r<l1) return; 25 if (l1<=l && r<=r1){Segt[now]=k; return;} 26 Pushdown(now); 27 int mid=(l+r)>>1; 28 Update(now<<1,l,mid,l1,r1,k); 29 Update(now<<1|1,mid+1,r,l1,r1,k); 30 } 31 32 int Query(int now,int l,int r,int x) 33 { 34 if (l==r) return Segt[now]; 35 Pushdown(now); 36 int mid=(l+r)>>1; 37 if (x<=mid) return Query(now<<1,l,mid,x); 38 else return Query(now<<1|1,mid+1,r,x); 39 } 40 41 int getid(int x) 42 { 43 int l=1,r=num; 44 while (l<=r) 45 { 46 int mid=(l+r)>>1; 47 if (id[mid]==x) return mid; 48 if (x<id[mid]) r=mid-1; 49 else l=mid+1; 50 } 51 } 52 53 int main() 54 { 55 scanf("%d%d",&n,&m); 56 for (int i=1; i<=m; ++i) 57 { 58 scanf("%d%d",&x[i],&y[i]); 59 id[++cnt]=x[i], id[++cnt]=y[i]; 60 id[++cnt]=x[i]+1,id[++cnt]=y[i]+1;//離散化的時候加入一個點兩邊的位置 61 id[++cnt]=x[i]-1,id[++cnt]=y[i]-1;//不這樣會掛 62 } 63 sort(id+1,id+cnt+1); 64 num=unique(id+1,id+cnt+1)-id-1; 65 for (int i=1; i<=m; ++i) 66 { 67 int xx=getid(x[i]),yy=getid(y[i]); 68 Update(1,1,num,xx,yy,i); 69 } 70 for (int i=1; i<=num; ++i) 71 { 72 int t=Query(1,1,num,i); 73 if (t && !vis[t]) ans++; 74 vis[t]=true; 75 } 76 printf("%d",ans); 77 }

5168. [HAOI2014]貼海報【線段樹】