题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4325
关于离散化的简介:http://blog.csdn.net/gokou_ruri/article/details/7723378
假如数据太大,无法作为数组下标来保存对应的属性而采取的一种方法。只需要关注相对大小即可。
我们记下所有的时间数据,再排序。通过二分查找快速定位元素的位置,然后在线段树或者树状数组上仅仅更新这个映射过后的下标位置。因为不需要从线段树或树状数组上直接获取数据(单纯的线段树或树状数组本身是没有意义的,需要搭配相应的数据操作才可以使其称之为线段树或树状数组),也就是说我们更新和查询都是要通过这样一次定位。这样可以解决空间不足的问题。排序后要去重,否则更新到时候可能会更新两次。
1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <climits> 6 #include <complex> 7 #include <fstream> 8 #include <cassert> 9 #include <cstdio> 10 #include <bitset> 11 #include <vector> 12 #include <deque> 13 #include <queue> 14 #include <stack> 15 #include <ctime> 16 #include <set> 17 #include <map> 18 #include <cmath> 19 20 using namespace std; 21 22 typedef struct Node { 23 int s; 24 int t; 25 }Node; 26 27 const int maxn = 1000010; 28 int n, m, cnt, tot; 29 int wt[maxn<<2]; 30 int bit[maxn]; 31 int ask[maxn]; 32 Node f[maxn]; 33 34 int lowbit(int x) { 35 return x & (-x); 36 } 37 38 void add(int i, int x) { 39 while(i <= cnt) { 40 bit[i] += x; 41 i += lowbit(i); 42 } 43 } 44 45 int sum(int i) { 46 int s = 0; 47 while(i > 0) { 48 s += bit[i]; 49 i -= lowbit(i); 50 } 51 return s; 52 } 53 54 int bs(int v) { 55 int ll = 0, rr = cnt - 1; 56 int mm; 57 while(ll <= rr) { 58 mm = (ll + rr) >> 1; 59 if(wt[mm] == v) return mm; 60 if(wt[mm] > v) rr = mm - 1; 61 if(wt[mm] < v) ll = mm + 1; 62 } 63 return -1; 64 } 65 66 inline bool scan_d(int &num) { 67 char in;bool IsN=false; 68 in=getchar(); 69 if(in==EOF) return false; 70 while(in!='-'&&(in<'0'||in>'9')) in=getchar(); 71 if(in=='-'){ IsN=true;num=0;} 72 else num=in-'0'; 73 while(in=getchar(),in>='0'&&in<='9'){ 74 num*=10,num+=in-'0'; 75 } 76 if(IsN) num=-num; 77 return true; 78 } 79 80 int main() { 81 // freopen("in", "r", stdin); 82 int T, _ = 1; 83 scan_d(T); 84 while(T--) { 85 tot = 0; 86 memset(bit, 0, sizeof(bit)); 87 scan_d(n); scan_d(m); 88 for(int i = 1; i <= n; i++) { 89 scan_d(f[i].s); scan_d(f[i].t); 90 wt[tot++] = f[i].s; wt[tot++] = f[i].t; 91 } 92 for(int i = 1; i <= m; i++) { 93 scan_d(ask[i]); 94 wt[tot++] = ask[i]; 95 } 96 sort(wt, wt+tot); 97 // int tot = unique(wt,wt+tot) - wt; 98 cnt = 1; 99 for(int i = 1; i < tot; i++) { 100 if(wt[i] != wt[i-1]) wt[cnt++] = wt[i]; 101 } 102 for(int i = 1; i <= n; i++) { 103 int x = bs(f[i].s) + 1; 104 int y = bs(f[i].t) + 1; 105 add(x, 1); 106 add(y+1, -1); 107 } 108 printf("Case #%d:\n", _++); 109 for(int i = 1; i <= m; i++) { 110 int ans = bs(ask[i]) + 1; 111 printf("%d\n", sum(ans)); 112 } 113 } 114 return 0; 115 }
来源:https://www.cnblogs.com/kirai/p/5432787.html