BZOJ1067SCOI2007降雨量(线段树)
Posted Lukaluka
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ1067SCOI2007降雨量(线段树)相关的知识,希望对你有一定的参考价值。
链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1067
水题QwQ 但是细节相当烦啊!!
1 #include <cstdio> 2 #include <cstdlib> 3 #include <iostream> 4 #include <algorithm> 5 #define MaxN 100010 6 #define MaxM 4000010 7 using namespace std; 8 int n, m, tot = 0, cnt = 0, S = 0, root; 9 int X[MaxN], Y[MaxN], sum[MaxN]; 10 int ls[MaxM], rs[MaxM], Max[MaxM]; 11 struct rec{ 12 int y, r; 13 }da[MaxN], map[MaxN]; 14 15 bool cmp(rec a, rec b){ 16 if (a.y == b.y) return a.r > b.r; 17 return a.y < b.y; 18 } 19 20 void Read_Data(){ 21 scanf("%d", &n); 22 for (int i = 1; i <= n; i++) ++tot, scanf("%d%d", &da[tot].y, &da[tot].r); 23 scanf("%d", &m); 24 for (int i = 1; i <= m; i++) { 25 scanf("%d%d", &X[i], &Y[i]); 26 da[++tot] = (rec) {X[i], 0}; 27 da[++tot] = (rec) {Y[i], 0}; 28 } 29 sort(da+1, da+1+tot, cmp); 30 map[++cnt] = da[1]; sum[1] = da[1].r > 0; 31 for (int i = 2; i <= tot; i++){ 32 if (da[i].y != da[i-1].y){ 33 ++cnt; 34 map[cnt] = da[i]; 35 sum[cnt] = sum[cnt-1] + (map[cnt].r > 0); 36 } 37 } 38 // for (int i = 1; i <= cnt; i++) cout<<map[i].y<<" "<<map[i].r<<endl; 39 } 40 41 void Build(int &x, int l, int r){ 42 x = ++S; 43 if (l == r){ 44 Max[x] = map[l].r; 45 return; 46 } 47 int mid = (l+r) >> 1; 48 Build(ls[x], l, mid); 49 Build(rs[x], mid+1, r); 50 Max[x] = max(Max[ls[x]], Max[rs[x]]); 51 } 52 53 int query(int x, int l, int r, int a, int b){ 54 if (l > r) return 0; 55 if (a <= l && b >= r) return Max[x]; 56 int mid = (l+r) >> 1, t = 0; 57 if (a <= mid) t = query(ls[x], l, mid, a, b); 58 if (b > mid) t = max(t, query(rs[x], mid+1, r, a, b)); 59 return t; 60 } 61 62 int query(int x, int y, int X, int Y){ 63 int MaxR = query(root, 1, cnt, x+1, y-1); 64 int vx = map[x].r, vy = map[y].r; 65 // printf("x%d y%d X%d Y%d max%d sum%d vx%d vy%d\n", x, y, X, Y, MaxR, sum[y]-sum[x-1], vx, vy); 66 if (!vy && !vx) return 1; 67 if (!vy && MaxR < vx) return 1; 68 if (!vx && MaxR < vy) return 1; 69 if (map[y].r <= map[x].r && MaxR < map[y].r && sum[y]-sum[x-1] != Y-X+1 && vx && vy) return 1; 70 if (map[y].r <= map[x].r && MaxR < map[y].r && sum[y]-sum[x-1] == Y-X+1 && vx && vy) return 2; 71 return 0; 72 } 73 74 int find(int x){ 75 int l = 1, r = cnt, mid; 76 while (l < r){ 77 mid = (l+r) >> 1; 78 if (x <= map[mid].y) r = mid; 79 else l = mid+1; 80 } 81 return l; 82 } 83 84 void Solve(){ 85 Build(root, 1, cnt); 86 int x, y, t; 87 for (int i = 1; i <= m; i++){ 88 x = find(X[i]), y = find(Y[i]); 89 t = query(x, y, X[i], Y[i]); 90 if (t == 0) printf("false\n"); 91 if (t == 1) printf("maybe\n"); 92 if (t == 2) printf("true\n"); 93 } 94 } 95 96 int main(){ 97 freopen("bzoj1067.in", "r", stdin); 98 freopen("bzoj1067.out", "w", stdout); 99 Read_Data(); 100 Solve(); 101 return 0; 102 }
以上是关于BZOJ1067SCOI2007降雨量(线段树)的主要内容,如果未能解决你的问题,请参考以下文章