luoguP2163 [SHOI2007]园丁的烦恼

https://www.luogu.org/problem/P2163

题意

如摘要所示,二位静态数点

分析

先,按照y为第一关键字,x为第二关键字排序,把n个数点,和询问的4*m个点都加进去,然后优先数点

这样就可以用关于 x 的树状数组进行求和和加点操作,进而用查询矩形的四个端点的sum加加减减就好了

可是这代码不知道为什么RE了一个点,,,以后再调吧

小伙伴们记得提醒博主这个傻子哦...

或者大佬能帮我调调....
(RE对于博主来说,只是常规操作..)

#include<cstdio>
#include<algorithm>
using namespace std;
const int MAX = 500000+99;
const int INF = 2147000047;

int n,m;
int t[MAX];
struct node{
    int xx, x, y;//x为离散化之后的x坐标
    int is;//is = 1表示数点, 0表示查询点
    //这样我们就可以在排序的时候分清数点与查询点 ,并且优先数点了
    int id;
    //用以按要求输出答案
    node(int xx=0, int y=0, int is=0, int id=0) : xx(xx), y(y), is(is), id(id) {}
}d[MAX*5];
bool cmp1(node a, node bb) {
    if(a.y == bb.y) {
        if(a.x == bb.x) return a.is > bb.is;
        return a.x < bb.x;
    }
    return a.y < bb.y;
}
bool cmp2(node a, node bb) {
    return a.xx < bb.xx;
}

int cnt, max_x, ans[MAX];//ans[id] = 第id个查询点的前缀和
void add_node(int xx, int y, int is, int id) {
    ++cnt;
    d[cnt] = node(xx, y, is, id);
}
bool cmp3(node a, node bb) {
    return a.id < bb.id;
}

void add(int x, int k) { while(x <= max_x) t[x] += k, x += x&(-x);}

int query(int x) {
    int res = 0;
    while(x) res += t[x], x -= x&(-x);
    return res;
}

void init() {
    scanf("%d%d",&n,&m);
    int x1, y1, x2, y2;
    for(int i = 1; i <= n; i++) {
        scanf("%d%d",&x1, &y1);
        add_node(x1, y1, 1, INF);
    }
    for(int i = 1; i <= (m<<2); i += 4) {
        scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
        add_node(x2, y2, 0, i);
        add_node(x1-1, y2, 0, i+1);
        add_node(x2, y1-1, 0, i+2);
        add_node(x1-1, y1-1, 0, i+3);
    }

    sort(d+1, d+1+cnt, cmp2);
    int tot = 1;
    d[1].x = 1;//记得初始化成1
    for(int i = 2; i <= cnt; i++) {
        if(d[i].xx != d[i-1].xx) ++tot;
        d[i].x = tot;
    }
    max_x = d[cnt].x;
//    for(int i = 1; i <= cnt; i++) {
//        if(d[i].is == 1) printf("数点:");
//        else printf("查询点%d为", d[i].id);
//        printf("%d %d\n", d[i].x, d[i].y);
//    }
}

void print_ans() {
    sort(d+1, d+1+cnt, cmp3);
    for(int i = 1; i <= (m<<2); i += 4) printf("%d\n", ans[i]-ans[i+1]-ans[i+2]+ans[i+3]);
}
void solve() {
    sort(d+1, d+cnt+1, cmp1);
    for(int i = 1; i <= cnt; i++) {
        if(d[i].is == 1) add(d[i].x, 1);//会重复加点吗
        else ans[d[i].id] = query(d[i].x);
    }
    print_ans();
}
int main() {
    init();
    solve();
    return 0;
}
/*
3 1
0 0
0 1
1 0
0 0 1 1
*/

原文地址:https://www.cnblogs.com/tyner/p/11565348.html

时间: 2024-10-10 10:17:38

luoguP2163 [SHOI2007]园丁的烦恼的相关文章

bzoj1935 [Shoi2007]园丁的烦恼

bzoj1935 [Shoi2007]园丁的烦恼 有N个点坐标为(xi,yi),M次询问,询问(a,b)-(c,d)的矩形内有多少点. 0≤n≤500000,1≤m≤500000,0≤xi,yi≤10000000 看完数据范围傻眼系列. 做法: 离线处理 因为这个范围肯定不能把x y都离散, 所以只把点和询问的y坐标放在一起都离散化,然后一起按x坐标排序, 再开一个树状数组,求出每个需要的点的二维前缀和. 不理解的话拿画图板画一下就好了. 细节见代码 #include<bits/stdc++.h

题解 P2163 【[SHOI2007]园丁的烦恼】

题目链接 Solution [SHOI2007]园丁的烦恼 题目大意:给定\(n\)棵树的坐标,每次询问以\((a,b)\)为左下端点,\((c,d)\)为右下端点的矩形内树的数量 题目大意:常规操作先二维前缀和一下: 记\(S_{i,j}\)为左下端点\((0,0)\),右上端点\((i,j)\)内的树的数量 然后每组询问的答案就是 \(ans = S_{c,d} - S_{a - 1,d} - S_{c,b-1}+S_{a-1,b-1}\) 我们的点就分为了两类:询问点和修改点 对于每个询问

BZOJ 1935 SHOI2007 园丁的烦恼 树状数组

题目大意:给定平面上的一些点,多次询问某个矩形中有多少个点 将每个询问拆成4个 然后把所有询问和点都按照横坐标排序 对于每个询问,将所有x值小于等于这个询问的x的点的y值加入树状数组 然后在树状数组上查询小于等于这个询问的y值的点的数量 别被1000W吓到了 如果不爆内存的话1E也是能搞的 套个log就没多少了 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm&

P2163 [SHOI2007]园丁的烦恼

#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int N=3e6+5; const int M=1e7+5; inline int read() { char c=getchar();int num=0; for(;!isdigit(c);c=getchar()

$[SHOI2007]$ 园丁的烦恼 二维数点/树状数组

\(Sol\) 设一个矩阵的左上角为\((x_1,y_1)\),右下角为\((x_2,y_2)\),\(s_{x,y}\)是到\((1,1)\)二维前缀和,那么这个矩阵的答案显然是\(s_{x_2,y_2}-s_{x_1-1,y_2}-s_{x_2,y_1-1}+s_{x_1-1,x_2-1}\).考虑把每个询问拆成这么四个二维前缀和的询问.将所有询问的\(s_{x,y}\)按照\(x\)排序,依次计算,这样我们就可以忽略\(x\)的限制而只考虑\(y\)的限制了.每次扫到一个询问,先把\(x\

BZOJ1935: [Shoi2007]Tree 园丁的烦恼

1935: [Shoi2007]Tree 园丁的烦恼 Description 很久很久以前,在遥远的大陆上有一个美丽的国家.统治着这个美丽国家的国王是一个园艺爱好者,在他的皇家花园里种植着各种奇花异草.有一天国王漫步在花园里,若有所思,他问一个园丁道: "最近我在思索一个问题,如果我们把花坛摆成六个六角形,那么--" "那么本质上它是一个深度优先搜索,陛下",园丁深深地向国王鞠了一躬. "嗯--我听说有一种怪物叫九头蛇,它非常贪吃苹果树--" &

bzoj1382 1935: [Shoi2007]Tree 园丁的烦恼

1935: [Shoi2007]Tree 园丁的烦恼 Time Limit: 15 Sec  Memory Limit: 357 MBSubmit: 1261  Solved: 578[Submit][Status][Discuss] Description 很久很久以前,在遥远的大陆上有一个美丽的国家.统治着这个美丽国家的国王是一个园艺爱好者,在他的皇家花园里种植着各种奇花异草.有一天国王漫步在花园里,若有所思,他问一个园丁道: "最近我在思索一个问题,如果我们把花坛摆成六个六角形,那么--&

1935: [Shoi2007]Tree 园丁的烦恼

1935: [Shoi2007]Tree 园丁的烦恼 Time Limit: 15 Sec  Memory Limit: 357 MBSubmit: 648  Solved: 273[Submit][Status][Discuss] Description 很久很久以前,在遥远的大陆上有一个美丽的国家.统治着这个美丽国家的国王是一个园艺爱好者,在他的皇家花园里种植着各种奇花异草.有一天国王漫步在花园里,若有所思,他问一个园丁道: “最近我在思索一个问题,如果我们把花坛摆成六个六角形,那么……”

BZOJ 1935: [Shoi2007]Tree 园丁的烦恼 [树状数组 离线 离散化]

传送门 刚才我还在郁闷网上怎么没人用$CDQ$分治做 突然发现根本没有时间序.... #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int N=3e6+5; inline int read(){ char c=getchar();int x=0,f=1; whi