题意:n( n <= 50000 ) 个线段,q ( q <= 50000) 个点,问每个点在几个线段上
线段端点的和询问的点的值都很大,所以必须离散化
第一种解法:先把所有的线段端点和询问点,离散处理,然后对于每条选段处理,c[x]++, c[y + 1]--,然后令c[x] = c[x] + c[x - 1],所以c[x]就保存了被几个线段覆盖,然后对对于每个询问点,查找他在离散后的位置,然后直接读取c[],这种方法很巧妙,佩服佩服
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 const int Max = 50000 + 10; 7 int c[4 * Max],a[Max],b[Max],querry[Max]; 8 int id[4 * Max],cnt; 9 int main() 10 { 11 int n, p, test; 12 scanf("%d", &test); 13 for(int t = 1; t <= test; t++) 14 { 15 printf("Case %d:\n", t); 16 scanf("%d%d", &n, &p); 17 memset(c, 0, sizeof(c)); 18 cnt = 0; 19 for(int i = 1; i <= n; i++) 20 { 21 scanf("%d%d", &a[i], &b[i]); 22 id[cnt++] = a[i]; 23 id[cnt++] = b[i]; 24 } 25 for(int i = 1; i <= p; i++) 26 { 27 scanf("%d", &querry[i]); 28 id[cnt++] = querry[i]; 29 } 30 sort(id, id + cnt); 31 cnt = unique(id, id + cnt) - id; 32 for(int i = 1; i <= n; i++) 33 { 34 int x = lower_bound(id, id + cnt, a[i]) - id; 35 int y = lower_bound(id, id + cnt, b[i]) - id; 36 c[x]++; 37 c[y + 1]--; 38 } 39 for(int i = 1; i < 3 * Max; i++) 40 c[i] += c[i - 1]; 41 42 for(int i = 1; i <= p; i++) 43 { 44 int x = lower_bound(id, id + cnt, querry[i]) - id; 45 printf("%d\n", c[x]); 46 } 47 } 48 return 0; 49 }