BZOJ1935. [Shoi2007]Tree 园丁的烦恼

[传送门]

 

把一个询问拆成4个询问,即二维前缀和的形式,又变成了二维矩阵求和/RMQ的问题,有了[51nod 1463找朋友]的启发,直接按$x$排序,再对$y$查询即可,区间前缀和可以用树状数组来实现,常数小而且好写。

 

#include <bits/stdc++.h>
using namespace std;

const int N = 2e6 + 7;
const int M = 5e6 + 7;
int n, m, Y[M], toty, ans[N];

namespace IO {
const int MAXSIZE = 1 << 24;
char buf[MAXSIZE], *p1, *p2;
#define gc()                                                               \
  (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, MAXSIZE, stdin), p1 == p2) \
       ? EOF                                                               \
       : *p1++)
inline int rd() {
  int x = 0, f = 1;
  char c = gc();
  while (!isdigit(c)) {
    if (c == '-') f = -1;
    c = gc();
  }
  while (isdigit(c)) x = x * 10 + (c ^ 48), c = gc();
  return x * f;
}
char pbuf[1 << 20], *pp = pbuf;
inline void push(const char &c) {
  if (pp - pbuf == 1 << 20) fwrite(pbuf, 1, 1 << 20, stdout), pp = pbuf;
  *pp++ = c;
}
inline void write(int x) {
  static int sta[35];
  int top = 0;
  do {
    sta[top++] = x % 10, x /= 10;
  } while (x);
  while (top) push(sta[--top] + '0');
}
} using namespace IO;

struct BIT {
    int tree[N];
    inline int lowbit(int x) {
        return x & -x;
    }
    void add(int x) {
        for (int i = x; i <= n; i += lowbit(i))
            tree[i]++;
    }
    int query(int x) {
        int ans = 0;
        for (int i = x; i; i -= lowbit(i))
            ans += tree[i];
        return ans;
    }
} bit;

struct IN {
    int x, y;
    inline bool operator < (const IN &rhs) const {
        return x < rhs.x || (x == rhs.x && y < rhs.y);
    }
} in[N];
vector<int> G[N];

struct QUERY {
    int x, y, id;
    bool flag;
    inline bool operator < (const QUERY &rhs) const {
        return x < rhs.x || (x == rhs.x && y < rhs.y);
    }
} query[M];

int main() {
    freopen("in.txt", "r", stdin);
    n = rd(), m = rd();
    int q = 0;
    for (int i = 1; i <= n; i++) {
        in[i].x = rd();
        in[i].y = rd();
        Y[++toty] = in[i].y;
    }
    for (int i = 1; i <= m; i++) {
        int a = rd(), b = rd(), c = rd(), d = rd();
        Y[++toty] = b - 1, Y[++toty] = d;
        query[++q] = (QUERY){a - 1, b - 1, i, 1};
        query[++q] = (QUERY){a - 1, d, i, 0};
        query[++q] = (QUERY){c, b - 1, i, 0};
        query[++q] = (QUERY){c, d, i, 1};
    }
    sort(Y + 1, Y + toty + 1);
    toty = unique(Y + 1, Y + 1 + toty) - Y - 1;
    for (int i = 1; i <= n; i++) 
        in[i].y = lower_bound(Y + 1, Y + toty + 1, in[i].y) - Y;
    for (int i = 1; i <= q; i++)
        query[i].y = lower_bound(Y + 1, Y + toty + 1, query[i].y) - Y;
    sort(in + 1, in + 1 + n);
    sort(query + 1, query + 1 + q);
    int now = 1;
    for (int i = 1; i <= q; i++) {
        while (now <= n && in[now].x <= query[i].x) {
            bit.add(in[now].y);
            now++;
        }
        if (query[i].flag == 1) {
            ans[query[i].id] += bit.query(query[i].y);
        } else {
            ans[query[i].id] -= bit.query(query[i].y);
        }
    }
    for (int i = 1; i <= m; i++) printf("%d\n", ans[i]);
    return 0;
}
View Code

 

posted @ 2019-10-14 18:30  Mrzdtz220  阅读(93)  评论(0编辑  收藏  举报