二维偏序问题应用(二维数点)

简介: 二维偏序问题应用(二维数点)


将二维数点问题转移为二维偏序问题来做,CDQ分治主席树也可以做,但是本人太菜,只会树状数组做法:

无需离散化写法:(注意询问数组开四倍,树状数组0没有意义+1)

#include <bits/stdc++.h>
using namespace std;
#define x first
#define y second
# define rep(i,be,en) for(int i=be;i<=en;i++)
# define pre(i,be,en) for(int i=be;i>=en;i--)
#define ll long long
#define endl "\n"
#define LOCAL
#define pb push_back
typedef pair<ll, ll> PII;
#define eb emplace_back
#define sp(i) setprecision(i)
const int N = 5e5 + 10, INF = 0x3f3f3f3f;
int n;
PII a[N];
int tr[10000005];
int m;
ll ans[N];
struct ques
{
  int x, y, id, type;
  ques(int _x = 0, int _y = 0, int _id = 0, int _type = 0)
  {
    x = _x;
    y = _y;
    id = _id;
    type = _type;
  }
  bool operator<(const ques &t)const
  {
    if (x == t.x)
      {
        return y < t.y;
      }
    else
      {
        return x < t.x;
      }
  }
} q[N << 2];
int cnt;
inline int lowbit(int x)
{
  return x & -x;
}
void modify(int x, int t)
{
  for (int i = x; i < 10000005; i += lowbit(i))
    {
      tr[i] += t;
    }
}
int  query(int x)
{
  ll sum = 0;
  for (int i = x; i; i -= lowbit(i))
    {
      sum += tr[i];
    }
  return sum;
}
void solve()
{
  cnt = 0;
  n = read();
  m = read();
  for (int i = 1; i <= n; i++)
    {
      a[i].x = read() + 1;
      a[i].y = read() + 1;
    }
  for (int i = 1; i <= m; i++)
    {
      int x1, x2, y1, y2;
      x1 = read() + 1;
      y1 = read() + 1;
      x2 = read() + 1;
      y2 = read() + 1;
      q[++cnt] = ques(x2, y2, i, 1);
      q[++cnt] = ques(x2, y1 - 1, i, -1);
      q[++cnt] = ques(x1 - 1, y2, i, -1);
      q[++cnt] = ques(x1 - 1, y1 - 1, i, 1);
    }
  sort(a + 1, a + 1 + n);
  sort(q + 1, q + 1 + cnt);
  int now = 1;
  for (int i = 1; i <= cnt; i++)
    {
      while (a[now].x <= q[i].x && now <= n)
        {
          modify(a[now].y, 1);
          now++;
        }
      ans[q[i].id] += 1LL * q[i].type * query(q[i].y);
    }
  for (int i = 1; i <= m; i++)
    {
      write(ans[i]);
      puts("");
    }
}
signed main()
{
  //#ifdef LOCAL
  //freopen("data.in.txt","r",stdin);
  //freopen("data.out.txt","w",stdout);
  //#endif
  int __ = 1;
  //cin >> __;
  while (__--)
    {
      solve();
    }
  return 0;
}

需要离散化写法

代码源oj 数数

这时要将两个数组放到一起

不需要加一,离散化会配好的:

/*********************************************************************
    程序名:
    版权:
    作者: Joecai
    日期: 2022-05-12 14:44
    说明:
*********************************************************************/
#include <bits/stdc++.h>
using namespace std;
#define x first
#define y second
# define rep(i,be,en) for(int i=be;i<=en;i++)
# define pre(i,be,en) for(int i=be;i>=en;i--)
#define ll long long
#define endl "\n"
#define LOCAL
#define pb push_back
#define int long long
typedef pair<ll, ll> PII;
#define eb emplace_back
#define sp(i) setprecision(i)
const int N = 1e6 + 10, INF = 0x3f3f3f3f;
int n, m;
int tr[N];
int t[N];
int ans[N];
inline int read()
{
  int X = 0;
  bool flag = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9')
    {
      if (ch == '-')
        flag = 0;
      ch = getchar();
    }
  while (ch >= '0' && ch <= '9')
    {
      X = (X << 1) + (X << 3) + ch - '0';
      ch = getchar();
    }
  if (flag)
    return X;
  return ~(X - 1);
}
inline void write(int X)
{
  if (X < 0)
    {
      X = ~(X - 1);
      putchar('-');
    }
  if (X > 9)
    write(X / 10);
  putchar(X % 10 + '0');
}
struct node
{
  int x;
  int y;
  int id;
  int type;
  node(int _x = 0, int _y = 0, int _id = 0, int _type = 0)
  {
    x = _x;
    y = _y;
    id = _id;
    type = _type;
  }
  bool operator<(const node &w)const
  {
    if (x == w.x)
      {
        if (y == w.y)
          {
            return id < w.id;
          }
        else
          return y < w.y;
      }
    else
      return x < w.x;
  }
} q[N];
inline int lowbit(int x)
{
  return x & (-x);
}
void up(int x, int s)
{
  for (int i = x; i < N; i += lowbit(i))
    {
      tr[i] += s;
    }
}
int query(int x)
{
  int sum = 0;
  for (int i = x; i; i -= lowbit(i))
    {
      sum += tr[i];
    }
  return sum;
}
void solve()
{
  int cnt = 0;
  memset(tr, 0, sizeof(tr));
  memset(ans, 0, sizeof(ans));
  cin >> n >> m;
  for (int i = 1; i <= n; i++)
    {
      int x;
      x = read();
      q[++cnt].x = i;
      q[cnt].y = x;
      q[cnt].type = 0;
      q[cnt].id = 0;
    }
  for (int i = 1; i <= m; i++)
    {
      int x, y, z;
      x = read();
      y = read();
      z = read();
      q[++cnt] = node(y, z, i, 1);
      q[++cnt] = node(x - 1, -1, i, 1);
      q[++cnt] = node(x - 1, z, i, -1);
      q[++cnt] = node(y, -1, i, -1);
    }
  for (int i = 1; i <= cnt; i++)
    t[i] = q[i].y;
  sort(q + 1, q + 1 + cnt);
  sort(t + 1, t + 1 + cnt);
  int te = unique(t + 1, t + 1 + cnt) - t - 1;
  for (int i = 1; i <= cnt; i++)
    {
      q[i].y = lower_bound(t + 1, t + 1 + te, q[i].y) - t;
    }
  for (int i = 1; i <= cnt; i++)
    {
      if (q[i].id) //查询的点
        {
          ans[q[i].id] += q[i].type * query(q[i].y);
        }
      else
        {
          up(q[i].y, 1);
        }
    }
  for (int i = 1; i <= m; i++)
    {
      write(ans[i]);
      printf(" ");
    }
  cout << endl;
}
signed main()
{
  //#ifdef LOCAL
  //freopen("data.in.txt","r",stdin);
  //freopen("data.out.txt","w",stdout);
  //#endif
  int __ = 1;
  cin >> __;
  while (__--)
    {
      solve();
    }
  return 0;
}

1

/*********************************************************************
    程序名:
    版权:
    作者: Joecai
    日期: 2022-05-12 16:20
    说明:
*********************************************************************/
#include <bits/stdc++.h>
using namespace std;
#define x first
#define y second
# define rep(i,be,en) for(int i=be;i<=en;i++)
# define pre(i,be,en) for(int i=be;i>=en;i--)
#define ll long long
#define endl "\n"
#define LOCAL
#define pb push_back
typedef pair<ll, ll> PII;
#define eb emplace_back
#define sp(i) setprecision(i)
const int N = 1e6 + 10, INF = 0x3f3f3f3f;
int n;
int tr[N];
inline int lowbit(int x)
{
  return x & (-x);
}
void up(int x, int s)
{
  for (int i = x; i < N; i += lowbit(i))
    {
      tr[i] += s;
    }
}
int query(int x)
{
  int sum = 0;
  for (int i = x; i; i -= lowbit(i))
    {
      sum += tr[i];
    }
  return sum;
}
struct node
{
  int x;
  int y;
  int id;
  int type;
  node(int _x = 0, int _y = 0, int _id = 0, int _type = 0)
  {
    x = _x;
    y = _y;
    id = _id;
    type = _type;
  }
  bool operator<(const node &w)const
  {
    if (x == w.x)
      {
        return y < w.y;
      }
    else
      return x < w.x;
  }
} q[N];
int t[N];
int ans[N];
void solve()
{
  int n;
  cin >> n;
  int cnt = 0;
  for (int i = 1; i <= n; i++)
    {
      int x, y;
      cin >> x >> y;
      q[++cnt].x = x;
      q[cnt].y = y;
      q[++cnt] = node(y, y, i, 1);
      q[++cnt] = node(x - 1, x - 1, i, 1);
      q[++cnt] = node(x - 1, y, i, -1);
      q[++cnt] = node(y, x - 1, i, -1);
    }
  sort(q + 1, q + 1 + cnt);
  for (int i = 1; i <= cnt; i++)
    t[i] = q[i].y;
  sort(t + 1, t + 1 + cnt);
  int te = unique(t + 1, t + 1 + cnt) - t - 1;
  for (int i = 1; i <= cnt; i++)
    {
      q[i].y = lower_bound(t + 1, t + 1 + te, q[i].y) - t;
    }
  for (int i = 1; i <= cnt; i++)
    {
      if (q[i].id)
        {
          ans[q[i].id] += q[i].type * query(q[i].y);
        }
      else
        up(q[i].y, 1);
    }
  for (int i = 1; i <= n; i++)
    {
      cout << ans[i] - 1 << endl;
    }
}
signed main()
{
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  //#ifdef LOCAL
  //freopen("data.in.txt","r",stdin);
  //freopen("data.out.txt","w",stdout);
  //#endif
  int __ = 1;
  //cin>>__;
  while (__--)
    {
      solve();
    }
  return 0;
}


目录
相关文章
|
Java 关系型数据库 MySQL
如何实现Springboot+camunda+mysql的集成
【7月更文挑战第2天】集成Spring Boot、Camunda和MySQL的简要步骤: 1. 初始化Spring Boot项目,添加Camunda和MySQL驱动依赖。 2. 配置`application.properties`,包括数据库URL、用户名和密码。 3. 设置Camunda引擎属性,指定数据源。 4. 引入流程定义文件(如`.bpmn`)。 5. 创建服务处理流程操作,创建控制器接收请求。 6. Camunda自动在数据库创建表结构。 7. 启动应用,测试流程启动,如通过服务和控制器开始流程实例。 示例代码包括服务类启动流程实例及控制器接口。实际集成需按业务需求调整。
999 4
|
机器学习/深度学习 数据可视化 Python
Scikit-Learn 中级教程——学习曲线
Scikit-Learn 中级教程——学习曲线
1050 3
|
算法 前端开发 C++
C++基础知识(八:STL标准库 deque )
deque在C++的STL(Standard Template Library)中是一个非常强大的容器,它的全称是“Double-Ended Queue”,即双端队列。deque结合了数组和链表的优点,提供了在两端进行高效插入和删除操作的能力,同时保持了随机访问的特性。
465 0
|
SQL 开发框架 .NET
技术心得:待处理(一)
技术心得:待处理(一)
92 0
|
人工智能 智能设计 云计算
阿里云LOGO设计智能生成入口网址
阿里云logo智能设计一键生成海量LOGO可供选择,阿里云百科分享阿里云LOGO设计生成网址链接以及使用方法,智能LOGO设计,仅需3步,10秒生成,AI匹配海量logo,商用无忧:
4373 1
阿里云LOGO设计智能生成入口网址
|
存储 SQL 关系型数据库
MySQL|什么情况下拓展字段长度会锁表?
作为产品DBA,经常被开发问,修改字段长度锁表吗?然后凭借"经验"给出回答:如果字段长度超过256个字符就会锁表。现在看来回答错误 。看看MySQL 官方文档Extending VARCHAR column sizeThe number of length bytes(字节) required by...
1106 0
MySQL|什么情况下拓展字段长度会锁表?
|
编解码 Oracle 关系型数据库
安装增强功能失败:Could not mount the media/drive C:\Program Files\Oracle\VirtualBox/VBoxGuestAdditions.iso
安装增强功能失败:Could not mount the media/drive C:\Program Files\Oracle\VirtualBox/VBoxGuestAdditions.iso
635 0
安装增强功能失败:Could not mount the media/drive C:\Program Files\Oracle\VirtualBox/VBoxGuestAdditions.iso
|
存储
【数据结构】线段树(入门)
【数据结构】线段树(入门)
134 0
【数据结构】线段树(入门)
|
存储 算法 安全
什么是 Hash 算法?
散列算法(Hash Algorithm),又称哈希算法,杂凑算法,是一种从任意文件中创造小的数字「指纹」的方法。与指纹一样,散列算法就是一种以较短的信息来保证文件唯一性的标志,这种标志与文件的每一个字节都相关,而且难以找到逆向规律。因此,当原有文件发生改变时,其标志值也会发生改变,从而告诉文件使用者当前的文件已经不是你所需求的文件。
什么是 Hash 算法?
|
机器学习/深度学习 Windows
Codeforces Round #748 (Div. 3) F - Red-Black Number (记忆化搜索)
Codeforces Round #748 (Div. 3) F - Red-Black Number (记忆化搜索)
172 0

热门文章

最新文章