cf E. Valera and Queries
http://codeforces.com/contest/369/problem/E
题意:输入n,m; n 代表有多少个线段,m代表有多少个询问点集。每一个询问输出这些点的集合所占的线段的个数。
思路:求出没有被点的覆盖的线段的个数,n-这个个数就是所求的。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define maxn 2000000 5 using namespace std; 6 const int inf=1e6+5; 7 8 int n,m; 9 int c[maxn]; 10 int ans[maxn]; 11 struct node 12 { 13 int l,r; 14 int id; 15 bool operator <(const node &a)const 16 { 17 return (r<a.r)||(r==a.r&&l<a.l); 18 } 19 } p[maxn],q[maxn]; 20 21 int low_bit(int x) 22 { 23 return x&(-x); 24 } 25 26 void add(int pos,int val) 27 { 28 while(pos<=inf) 29 { 30 c[pos]+=val; 31 pos+=low_bit(pos); 32 } 33 } 34 35 int sum(int pos) 36 { 37 int sum1=0; 38 while(pos>0) 39 { 40 sum1+=c[pos]; 41 pos-=low_bit(pos); 42 } 43 return sum1; 44 } 45 46 int main() 47 { 48 while(scanf("%d%d",&n,&m)!=EOF) 49 { 50 for(int i=0; i<n; i++) 51 { 52 scanf("%d%d",&p[i].l,&p[i].r); 53 p[i].id=i+1; 54 } 55 sort(p,p+n); 56 int cnt=0; 57 for(int i=1; i<=m; i++) 58 { 59 ans[i]=n; 60 } 61 for(int i=1; i<=m; i++) 62 { 63 int num,x; 64 scanf("%d",&num); 65 int last=0; 66 for(int j=1; j<=num; j++) 67 { 68 scanf("%d",&x); 69 q[cnt].l=last; 70 q[cnt].r=x; 71 q[cnt++].id=i; 72 last=x; 73 } 74 q[cnt].l=x; 75 q[cnt].r=inf; 76 q[cnt++].id=i; 77 } 78 sort(q,q+cnt); 79 int j=0; 80 for(int i=0; i<cnt; i++) 81 { 82 while(j<n&&p[j].r<q[i].r) 83 { 84 add(p[j++].l,1); 85 } 86 ans[q[i].id]-=sum(q[i].r-1)-sum(q[i].l); 87 } 88 for(int i=1; i<=m; i++) 89 { 90 printf("%d\n",ans[i]); 91 } 92 } 93 return 0; 94 }