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降雨量(线段树)的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 1067: [SCOI2007]降雨量

bzoj 1067: [SCOI2007]降雨量

BZOJ 1067 [SCOI2007]降雨量

[BZOJ 1067][SCOI2007]降雨量

洛谷 2471 BZOJ 1067 [SCOI2007]降雨量

1067. [SCOI2007]降雨量线段树