http://acm.hdu.edu.cn/showproblem.php?pid=4325
题意:
有n种花每种开放的时间从a到b(a到b的闭区间),问t时刻有多少种花开着(n<=10^6,a<=b<10^9)
1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 using namespace std; 5 const int Ni = 1000010; 6 struct node { 7 int l,r,sum; 8 }tree[Ni*3]; 9 struct node1{ 10 int l,r; 11 }flo[Ni]; 12 int x[Ni*2]; 13 int n,m; 14 void build(int l,int r,int i) 15 { 16 tree[i].l=x[l];tree[i].r=x[r]; 17 tree[i].sum=0; 18 if(l==r) return ; 19 int mid=(l+r)>>1; 20 build(l,mid,i<<1); 21 build(mid+1,r,i<<1|1); 22 } 23 void update(int l,int r,int i) 24 { 25 if(l<=tree[i].l&&tree[i].r<=r) 26 {tree[i].sum++;return;} 27 28 if(r<=tree[i<<1].r) update(l,r,i<<1); 29 else if(l>=tree[i<<1|1].l) update(l,r,i<<1|1); 30 else 31 { 32 update(l,tree[i<<1].r,i<<1); 33 update(tree[i<<1|1].l,r,i<<1|1); 34 } 35 } 36 int qurey(int key,int i) 37 { 38 int ans=tree[i].sum; 39 if(tree[i].l==tree[i].r)//到叶子结点 40 return tree[i].sum; 41 if(key<=tree[i<<1].r)//在左子树 42 return ans+qurey(key,i<<1); 43 if(key>=tree[i<<1|1].l)//在右子树 44 return ans+qurey(key,i<<1|1); 45 int a=qurey(key,i<<1);//在中间 46 int b=qurey(key,i<<1|1); 47 ans+=min(a,b); 48 return ans; 49 } 50 int main() 51 { 52 int cs=1,i,t,q,num; 53 cin>>t; 54 for(cs=1;cs<=t;cs++) 55 { 56 cin>>n>>m; 57 for(num=i=0;i<n;i++) 58 { 59 scanf("%d%d",&flo[i].l,&flo[i].r); 60 x[num++]=flo[i].l; 61 x[num++]=flo[i].r; 62 } 63 sort(x,x+num); 64 num=(num-1)<<1; 65 for(i=num;i>=0;i-=2)//插点 66 { 67 x[i]=x[i>>1]; 68 x[i-1]=(x[i>>1]+x[(i>>1)-1])>>1; 69 } 70 for(i=1,q=0;i<=num;i++)//缩点 71 { 72 if(x[q]!=x[i]) x[++q]=x[i]; 73 } 74 build(0,num=q,1);//0到num的结点建树 75 for(i=0;i<n;i++) 76 { 77 update(flo[i].l,flo[i].r,1); 78 } 79 printf("Case #%d:\n",cs); 80 for(i=0;i<m;i++) 81 { 82 scanf("%d",&q); 83 if(q<x[0]||q>x[num]) printf("0\n"); 84 else 85 printf("%d\n",qurey(q,1)); 86 } 87 } 88 return 0; 89 } 90 /* 91 1 92 3 100 93 4 5 94 2 7 95 7 10 96 6 97 */