做过的线段树题目大多是,对于整体的数据范围0-m根据给出的点做区间划分,然后再统计数据。
对于m很大的,有些需要离散化
操作的时候分为在线和离线操作
1 #include <iostream> 2 #include <cstring> 3 #include <string> 4 #include <map> 5 #include <set> 6 #include <algorithm> 7 #include <fstream> 8 #include <cstdio> 9 #include <cmath> 10 #include <stack> 11 #include <queue> 12 #define mem(x) memset(x,0,sizeof(x)) 13 #define lson l,m,rt<<1 14 #define rson m+1,r,rt<<1|1 15 using namespace std; 16 typedef long long ll; 17 const int maxn=21111; 18 bool hash[maxn]; 19 int li[maxn],ri[maxn]; 20 int X[maxn*3]; 21 int col[maxn*4]; 22 int cnt; 23 24 void Pushdown(int rt){ 25 if(col[rt]!=-1){ 26 col[rt<<1]=col[rt<<1|1] =col[rt]; 27 col[rt]=-1; 28 } 29 } 30 31 void Update(int L,int R,int c,int l,int r,int rt){ 32 if(L<=l&&r<=R){ 33 col[rt]=c; 34 return; 35 } 36 Pushdown(rt); 37 int m=(l+r)>>1; 38 if(L<=m) Update(L,R,c,lson); 39 if(m<R) Update(L,R,c,rson); 40 } 41 void Query(int l,int r,int rt){ 42 if(col[rt]!=-1){ 43 if(!hash[col[rt]]) cnt++; 44 hash[col[rt]]=1; 45 return; 46 } 47 if(l==r) return; 48 int m=(l+r)>>1; 49 Query(lson); 50 Query(rson); 51 } 52 53 int Bin(int key,int n,int X[]){ 54 int l=0,r=n-1; 55 while(l<=r){ 56 int m=(l+r)>>1; 57 if(X[m]==key) return m; 58 if(X[m]<key) l=m+1; 59 else r=m-1; 60 } 61 return -1; 62 } 63 64 int main(){ 65 int T,n; 66 scanf("%d",&T); 67 while(T--){ 68 scanf("%d",&n); 69 int nn=0; 70 for(int i=0;i<n;i++){ 71 scanf("%d%d",&li[i],&ri[i]); 72 X[nn++]=li[i]; 73 X[nn++]=ri[i]; 74 } 75 sort(X,X+nn); 76 int m=1; 77 for(int i=1;i<nn;i++){ 78 if(X[i]!=X[i-1]) X[m++]=X[i]; 79 } 80 for(int i=m-1;i>0;i--){ 81 if(X[i]!=X[i-1]+1) X[m++]=X[i-1]+1; 82 } 83 sort(X,X+m); 84 memset(col,-1,sizeof(col)); 85 86 for(int i=0;i<n;i++){ 87 int l=Bin(li[i],m,X); 88 int r=Bin(ri[i],m,X); 89 90 Update(l,r,i,0,m,1); 91 } 92 cnt=0; 93 mem(hash); 94 Query(0,m,1); 95 printf("%d\n",cnt); 96 } 97 return 0; 98 }