首页 > 其他分享 >P2163 [SHOI2007] 园丁的烦恼 题解

P2163 [SHOI2007] 园丁的烦恼 题解

时间:2024-07-31 11:55:54浏览次数:16  
标签:x1 int 题解 sum P2163 x2 y1 SHOI2007 y2

题目传送门

题目大意:

在一个平面直角坐标系上,给定 \(n\) 个点的坐标 \((x,y)\),\(m\) 次询问,每次询问一个矩形范围内的点的数量,此矩形用 \(\{a, b, c, d\}\) 来描述,其中 \((a, b)\) 为左下角,\((c, d)\) 为右上角。

思路:

不难将题目转化为:给定一个长度为 \(n\) 的序列,序列中的每个元素都有两个属性 \(x,y\),每次询问求 \(x\in [a, c]\) 且 \(y\in [b, d]\) 的元素个数。

这道题 差不多的思路,都用类似前缀和的思想,但这道题是二维前缀和。

对于一个询问,我们要处理的其实是这样一个图形:

其中四边形 \(\text{AGBH}\) 是我们要求的。

设此询问为 \(\{x1, y1, x2, y2\}\)
\(A(x1 - 1, y1 - 1)\)
\(E(x1 - 1, y2)\)
\(G(x2, y1 - 1)\)
\(B(x2, y2)\)

设左下角为 \((0, 0)\),右上角为 \((i, j)\) 的矩形中点的数量为 \(sum_{i, j}\)。

所以我们要求的是 \(sum_{x2, y2} + sum_{x1 - 1, y1 - 1} - sum_{x1 - 1, y2} - sum_{x2, y1 - 1}\)。

将询问分成四个部分,分别存 \(A,E,G,B\) 四个,然后将给定的点和询问都按照 \(x\) 升序排列,这样 \(x\) 的限制就可以不用管了,再建立一个树状数组来维护 \(y\) 即可。

需要注意的几个点:

  1. 本题值域较大,需要离散化;(其实也没有那么大,不离散化也能过)
  2. 离散化后的数要从 \(1\) 开始,因为为 \(0\) 的话树状数组会死循环;
  3. 询问要分成 \(4\) 份,也就是说要开 \(4\) 倍空间,同理,树状数组的值域也要开大点。

\(\texttt{Code:}\)

#include <vector>
#include <iostream>
#include <algorithm>

#define lowbit(x) x & -x
using namespace std;

const int N = 500010, M = 20000010;

int n, m;
struct BIT{
    int c[M];
    void add(int x, int y) {
        for(; x < M; x += lowbit(x)) c[x] += y;
    }
    int ask(int x) {
        int res = 0;
        for(; x; x -= lowbit(x)) res += c[x];
        return res; 
    }
}tr;
vector<int> nums;
struct node{
    int id, x, y, sign;
    bool operator< (const node &o) const {
        return x < o.x;
    }
}q[N << 2];
int tt;
struct Point{
    int x, y;
    bool operator< (const Point &o) const {
        return x < o.x;
    }
}a[N];
int ans[N];

int find(int x) {
    return lower_bound(nums.begin(), nums.end(), x) - nums.begin() + 1;
}

int main() {
    scanf("%d%d", &n, &m);
    int x, y;
    for(int i = 1; i <= n; i++) {
        scanf("%d%d", &x, &y);
        a[i] = {x, y};
        nums.push_back(y);
    }
    int x1, y1, x2, y2;
    for(int i = 1; i <= m; i++) {
        scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
        q[++tt] = {i, x1 - 1, y1 - 1, 1};
        q[++tt] = {i, x1 - 1, y2, -1};
        q[++tt] = {i, x2, y1 - 1, -1};
        q[++tt] = {i, x2, y2, 1};
        nums.push_back(y1 - 1), nums.push_back(y2);
    }
    sort(nums.begin(), nums.end());
    nums.erase(unique(nums.begin(), nums.end()), nums.end());
    sort(a + 1, a + n + 1);
    sort(q + 1, q + tt + 1);
    int id = 1;
    for(int i = 1; i <= tt; i++) {
        while(a[id].x <= q[i].x && id <= n) tr.add(find(a[id++].y), 1);
        ans[q[i].id] += q[i].sign * tr.ask(find(q[i].y));
    }
    for(int i = 1; i <= m; i++)
        printf("%d\n", ans[i]);
    return 0;
}

标签:x1,int,题解,sum,P2163,x2,y1,SHOI2007,y2
From: https://www.cnblogs.com/Brilliant11001/p/18334342

相关文章

  • CF1997(edu168)题解 A-F
    A.StrongPassword注意到最大效果是在两个相同字符之间插入一个不同的,贡献为3。否则在一开始插入一个和首位不同的,贡献为2。#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;voidsolve(){strings;cin>>s;boolok=0;for(inti......
  • 【题解】2024牛客多校第5场
    E安https://ac.nowcoder.com/acm/contest/81600/E分析简单博弈/思维题。当ai>bi时,当前骑士一定存活。当ai<bi时,当前骑士一定死亡。为了使得自己存活的骑士尽可能多,若存在ai=bi的情况,一定会选择令该骑士去攻击对方,并且双方均会轮流优先选择此类骑士。......
  • 07-30 题解
    07-30题解A朴素的想法$dp(i,j,k)$表示考虑到第\(i\)位,前\(i\)位的和为\(j\),第\(i\)位的值为\(k\)然后咋转移?重新定义移动小球的方式:从自己右边的邻居拿过来正数个球拿过来负数个球(即往右边的邻居放正数个球)在第2种操作中,我们拿走的球会被后面放过来......
  • Luogu P1983 车站分级 题解 [ 绿 ] [ 拓扑排序 ] [ 图论建模 ] [ 虚点 ]
    车站分级:很好的拓扑排序题,细节有点多。图论建模首先观察对于一条线路,我们可以从中直接得到什么信息:假设这条线路的开头为\(st\),结尾为\(ed\),那么在\([st,ed]\)的车站中,没有被选入线路的点一定比选入线路的点的级数至少少\(1\)。对于这一点条件,我们就可以建模了。......
  • CF538H Summer Dichotomy 题解
    Description有\(T\)名学生,你要从中选出至少\(t\)人,并将选出的人分成两组,可以有某一组是空的。有\(n\)名老师,每名老师要被分配到两个小组之一,对于第\(i\)名老师,要求所在的小组中的学生人数\(\in[l_i,r_i]\)。此外,有\(m\)对老师不能在同一个小组中。你需要判断能否......
  • SP8099 TABLE - Crash´s number table 题解
    题目传送门前置知识一般的积性函数|数论分块|莫比乌斯反演解法令\(n\lem\)。考虑莫比乌斯反演,推式子,有\(\begin{aligned}&\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}\operatorname{lcm}(i,j)\\&=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}\frac{ij}{\gcd(i,j)......
  • 题解:Pinely Round 4 (Div. 1 + Div. 2) A
    A.MaximizetheLastElementtimelimitpertest:1secondmemorylimitpertest:256megabytesinput:standardinputoutput:standardoutputYouaregivenanarray\(a\)of\(n\)integers,where\(n\)isodd.Inoneoperation,youwillremovetwoa......
  • P4449 于神之怒加强版 (题解)
    题目链接P4449于神之怒加强版题目大意:求\[\sum_{i=1}^{n}\sum_{j=1}^{m}gcd(i,j)^k\]\(数据范围n,m\leq5e6\)\(二话不说,先开导式子(假定n<m):\)\begin{aligned}ans&=\sum_{i=1}^{n}\sum_{j=1}^{m}gcd(i,j)^k\\\end{aligned}\[先套路地枚举d=gcd(i,j)\]\begin{align......
  • 题解 - Alice
    题目描述Alice和Bob在玩游戏,游戏规则如下:有两堆石子,每堆石子有非负整数个Alice与Bob轮流操作,Alice先手,每次可以从任意一堆石子中取出若干个取出的石子个数应满足为另一堆石子个数的因数(此处规定任何数均为0的因数)将石子取完的玩家获胜给定一个初始状态,现......
  • [POI2007] OSI-Axes of Symmetry 题解
    给出一个多边形,求对称轴数量。考虑对于一个多边形,其是对称的当且仅当对于若干个边(角),其左右的角与边都是对称的。考虑如果我们对于内角构造出一种单射,映射为一个整数,将边映射为它的边长,那么我们按照角,边,角,边,……的顺序将他们加入数组中,能构造出一个长度为\(2n\)的数组,将这个......