社区讨论

帮同学问,90 求条

P2163[SHOI2007] 园丁的烦恼参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@mivoofah
此快照首次捕获于
2025/12/07 20:13
2 个月前
此快照最后确认于
2025/12/07 20:13
2 个月前
查看原帖
UnionRE问,他被禁言了。
同时问一下线段树能不能过这道题。(这份代码空间开小了 WA,开大了 MLE)
CPP
#include<bits/stdc++.h>

#define endl '\n'
using namespace std;
const int maxn = 1e6 + 10;  // 增大数组大小
int a[maxn], tot, tx, ty, tot2, ans[maxn];
struct tr {
    int x, y, id;
    friend bool operator<(tr aa, tr bb) {
        return aa.x < bb.x;
    }
} v[maxn];
struct qry {
    int a, b, c, d, id;
} b[maxn];
struct qry2 {
    int x, y, type, id;
    friend bool operator<(qry2 aa, qry2 bb) {
        return aa.x < bb.x;
    }
} q[maxn * 4];
int bx[maxn], by[maxn];
int getx(int x) { return lower_bound(bx + 1, bx + tx + 1, x) - bx; }
int gety(int y) { return lower_bound(by + 1, by + ty + 1, y) - by; }
struct node {
    int l, r, sum;
} t[maxn * 4];
#define ls id<<1
#define rs id<<1|1
void up(int id) { t[id].sum = t[ls].sum + t[rs].sum; }
void build(int id, int l, int r) {
    t[id].l = l, t[id].r = r;
    if (l == r) {
        t[id].sum = 0;
        return;
    }
    int mid = (l + r) >> 1;
    build(ls, l, mid);
    build(rs, mid + 1, r);
    up(id);
}
void add(int id, int x) {
    if (t[id].r < x || t[id].l > x) return;
    if (t[id].l == t[id].r && t[id].l == x) {
        t[id].sum++;
        return;
    }
    add(ls, x), add(rs, x);
    up(id);
}
int query(int id, int l, int r) {
    if (t[id].r < l || t[id].l > r) return 0;
    if (l <= t[id].l && t[id].r <= r) return t[id].sum;
    return query(ls, l, r) + query(rs, l, r);
}
signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        int x, y;
        cin >> x >> y;
        v[i] = {x, y, i};
        bx[++tx] = x, by[++ty] = y;
    }
    for (int i = 1; i <= m; i++) {
        int A, B, C, D;
        cin >> A >> B >> C >> D;
        b[i] = {A, B, C, D, i};
        bx[++tx] = A, bx[++tx] = C;
        by[++ty] = B, by[++ty] = D;
    }
    
    // 添加0,确保A-1和B-1不会越界
    bx[++tx] = -1;
    by[++ty] = -1;
    
    sort(bx + 1, bx + tx + 1);
    sort(by + 1, by + ty + 1);
    tx = unique(bx + 1, bx + tx + 1) - bx - 1;
    ty = unique(by + 1, by + ty + 1) - by - 1;
    
    // 找到-1的位置作为0的映射
    int zero_x = lower_bound(bx + 1, bx + tx + 1, -1) - bx;
    int zero_y = lower_bound(by + 1, by + ty + 1, -1) - by;
    
    for (int i = 1; i <= n; i++) {
        v[i] = {getx(v[i].x), gety(v[i].y), v[i].id};
    }
    for (int i = 1; i <= m; i++) {
        int a_val = getx(b[i].a);
        int b_val = gety(b[i].b);
        int c_val = getx(b[i].c);
        int d_val = gety(b[i].d);
        
        // 处理A-1,B-1的情况
        int a_minus_1 = a_val - 1;
        int b_minus_1 = b_val - 1;
        
        q[++tot2] = {c_val, d_val, 1, i};
        q[++tot2] = {a_minus_1, b_minus_1, 1, i};
        q[++tot2] = {a_minus_1, d_val, -1, i};
        q[++tot2] = {c_val, b_minus_1, -1, i};
    }
    
    // 构建线段树,大小设为ty+1
    build(1, 0, ty + 5);
    
    sort(v + 1, v + n + 1);
    sort(q + 1, q + tot2 + 1);
    
    int k = 1;
    for (int i = 1; i <= tot2; i++) {
        while (k <= n && v[k].x <= q[i].x) {
            add(1, v[k].y);
            k++;
        }
        // 查询时确保y不小于0
        int y = max(0, q[i].y);
        ans[q[i].id] += q[i].type * query(1, 0, y);
    }
    
    for (int i = 1; i <= m; i++) cout << ans[i] << endl;
    return 0;
}
```****

回复

0 条回复,欢迎继续交流。

正在加载回复...