首页 > 其他分享 >二维数点/二维偏序

二维数点/二维偏序

时间:2023-12-01 16:57:21浏览次数:27  
标签:偏序 cur int ll 数点 long 二维

二维数点/二维偏序

模型:

给定二维点集,给定矩阵集,问每个矩阵中有多少个点。

此处二维偏序关系的问题也大都如此。

这里使用树状数组和二维前缀和容斥拆解思想求解。

例题:

P2163 [SHOI2007] 园丁的烦恼

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
typedef pair<int, int> pii;
#define fi first
#define se second
const int N = 5e5 + 10;
int n, m;
int tr[N];
struct node
{
    int x, y, val, id;
    bool operator<(node t)
    {
        if (x != t.x)
        {
            return x < t.x;
        }
        else
        {
            return y < t.y;
        }
    }
};

int lowbit(int x)
{
    return x & -x;
}

void update(int idx, int val)
{
    for (int i = idx; i <= N - 1; i += lowbit(i))
    {
        tr[i] += val;
    }
}

int query(int idx)
{
    ll res = 0;
    for (int i = idx; i; i -= lowbit(i))
    {
        res += tr[i];
    }
    return res;
}

void solve()
{

    scanf("%d %d", &n, &m);
    vector<pii> v(n + 1);
    vector<int> p;
    for (int i = 1; i <= n; i++)
    {
        scanf("%d %d", &v[i].fi, &v[i].se);
        v[i].fi++;
        v[i].se++;
        p.push_back(v[i].fi);
        p.push_back(v[i].se);
    }
    vector<node> q(1);
    for (int i = 1; i <= m; i++)
    {
        int x1, x2, y1, y2;
        scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
        x1++;
        x2++;
        y1++;
        y2++;
        q.push_back({x1 - 1, y1 - 1, 1, i});
        q.push_back({x1 - 1, y2, -1, i});
        q.push_back({x2, y1 - 1, -1, i});
        q.push_back({x2, y2, 1, i});
        p.push_back(x1 - 1);
        p.push_back(y1 - 1);
        p.push_back(x1 - 1);
        p.push_back(y1 - 1);
        p.push_back(x2);
        p.push_back(y2);
    }
    sort(p.begin(), p.end());
    p.erase(unique(p.begin(), p.end()), p.end());
    auto find = [&](int x)
    {
        int t = lower_bound(p.begin(), p.end(), x) - p.begin() + 1;
        return t;
    };
    sort(v.begin() + 1, v.end());
    sort(q.begin() + 1, q.end());
    int cur = 1;
    vector<int> ans(m + 1);
    for (int i = 1; i <= q.size() - 1; i++)
    {
        while (cur <= n && v[cur].fi <= q[i].x)
        {
            int t = find(v[cur].se);
            // cout << t << ' ' << v[cur].se << endl;
            update(t, 1);
            cur++;
        }
        // cout << q[i].id << ' ' << q[i].x << ' ' << q[i].y << ' ' << find(q[i].y) << ' ' << query(find(q[i].y)) * q[i].val << endl;
        ans[q[i].id] += query(find(q[i].y)) * q[i].val;
    }
    for (int i = 1; i <= m; i++)
    {
        printf("%lld\n", ans[i]);
    }
}

int main()
{
    int t = 1;
    while (t--)
    {
        solve();
    }
    return 0;
}

P3755 [CQOI2017] 老C的任务

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
typedef pair<int, int> pii;
#define fi first
#define se second
const int N = 1e6 + 10;
int n, m;
ll tr[N];
struct node
{
    ll x, y, val, id;
    bool operator<(node t)
    {
        if (x != t.x)
        {
            return x < t.x;
        }
        else
        {
            return y < t.y;
        }
    }
};

struct base
{
    ll x, y, p;
    bool operator<(base t)
    {
        if (x != t.x)
        {
            return x < t.x;
        }
        else
        {
            return y < t.y;
        }
    }
};

ll lowbit(int x)
{
    return x & -x;
}

void update(int idx, int val)
{
    for (int i = idx; i <= N - 1; i += lowbit(i))
    {
        tr[i] += val;
    }
}

ll query(int idx)
{
    ll res = 0;
    for (int i = idx; i; i -= lowbit(i))
    {
        res += tr[i];
    }
    return res;
}

void solve()
{
    cin >> n >> m;
    vector<ll> d;
    vector<base> v(1);
    for (int i = 1; i <= n; i++)
    {
        ll x, y, p;
        scanf("%lld %lld %lld", &x, &y, &p);
        v.push_back({x, y, p});
        // d.push_back(x);
        d.push_back(y);
    }
    vector<node> q(1);
    for (int i = 1; i <= m; i++)
    {
        ll x1, y1, x2, y2;
        scanf("%lld %lld %lld %lld", &x1, &y1, &x2, &y2);
        q.push_back({x1 - 1, y1 - 1, 1, i});
        q.push_back({x1 - 1, y2, -1, i});
        q.push_back({x2, y1 - 1, -1, i});
        q.push_back({x2, y2, 1, i});
        // d.push_back(x1);
        // d.push_back(y1);
        // d.push_back(x1 - 1);
        d.push_back(y1 - 1);
        // d.push_back(x2);
        d.push_back(y2);
    }
    sort(d.begin(), d.end());
    d.erase(unique(d.begin(), d.end()), d.end());
    auto find = [&](ll x) -> ll
    {
        auto t = lower_bound(d.begin(), d.end(), x) - d.begin() + 1;
        return t;
    };
    vector<ll> ans(m + 1);
    sort(v.begin() + 1, v.end());
    sort(q.begin() + 1, q.end());
    int cur = 1;
    for (int i = 1; i < q.size(); i++)
    {
        while (cur <= n && q[i].x >= v[cur].x)
        {
            auto t = find(v[cur].y);
            update(t, v[cur].p);
            cur++;
        }
        ans[q[i].id] += query(find(q[i].y)) * q[i].val;
    }
    for (int i = 1; i <= m; i++)
    {
        printf("%lld\n", ans[i]);
    }
}

int main()
{
    int t = 1;
    while (t--)
    {
        solve();
    }
    return 0;
}

标签:偏序,cur,int,ll,数点,long,二维
From: https://www.cnblogs.com/value0/p/17870426.html

相关文章

  • 基于MUSIC算法的二维超声波成像matlab仿真
    1.算法运行效果图预览  2.算法运行软件版本matlab2022a 3.算法理论概述      MUSIC(MultipleSignalClassification)算法是一种广泛应用于信号处理领域的算法,它可以用于估计信号的波达方向或频率。在超声波成像中,MUSIC算法可以用于提高图像的分辨率和降低......
  • 将表格的列标题作为第一行, 转为二维list
    #将表格的列标题作为第一行,转为二维list#情况1_1,表格,无数据;情况1_2,表格,有数据data=[[1,1]]columns=['col1','col2']df=pd.DataFrame(data=data,columns=columns)df_concat=pd.concat([#to_frame(index:'bool'=True,name:'Hashab......
  • 金山胖&你竟然赶我走&二维码
    金山胖WP1.题目压缩包打开,给了一张gif没做过misc哈哈哈,感觉杂项还挺有意思的2.解题wps方式,选择GIF编辑,,,答案藏在21帧,51帧,79帧三部分连起来,flagflag{he11ohongke}你竟然赶我走一张jpg记事本打开,ctrl+f搜索flag,,,,找到了,在末尾flagflag{stego_is_s0_bor1ing}......
  • java-生成二维码/条形码
    前言:  需求:生成二维码/条形码//使用ZXing库<dependencies><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.4.1</version></dependency>&l......
  • (查找)02-二维数组中的查找
    1importjava.util.*;23publicclassSolution{4/**5*@paramtargetint整型6*@paramarrayint整型二维数组7*@returnbool布尔型8*/9publicbooleanFind(inttarget,int[][]array){10//判空矩阵1......
  • 数组(3)二维数组
    <1>二维数组的基本内容(1)基本了解举例:inta[3][5];概念:可以将a理解为一个三行五列的矩阵;(由此证明3代表行,5代表列)(2)二维数组的遍历代码:for(i=0;i<3;i++){for(j=0;j<5;j++){a[i][j]=i*j;}}a[i][j]是一个int;表示第i行和第j列上的单元;提出问题:a[i,j]表示的含......
  • .NET生成微信小程序推广二维码
    前言对于小程序大家可能都非常熟悉了,随着小程序的不断普及越来越多的公司都开始推广使用起来了。今天接到一个需求就是生成小程序码,并且与运营给的推广图片合并在一起做成一张漂亮美观的推广二维码,扫码这种二维码就可以进入小程序。为了节省服务器内存资源,我想的就是成功调用通微......
  • python保留小数点后几位的方法
    一、保留小数点后n位方法一:使用字符串格式化注意:使用字符串格式化后的是字符串格式a=12.3456print("%.3f"%a)#保留小数点后三位print("%.2f"%a)#保留小数点后两位输出12.34612.35方法二:使用round内置函数注意:使用round后的是浮点数格式a=12.3456a1=round(a......
  • OpenCASCADE二维曲线求交
    OpenCASCADE二维曲线求交1IntroductionOpenCASCADE中对二维曲线求交和三维曲线求交是不同的,三维曲线求交统一使用离散法,二维曲线求交根据曲线类型的不同分种类型进行处理。二维曲线求交中还提供了计算自交的直接接口。在TKGeomAlgo中,主要内容就是拟合、求交算法,理解求交算法的......
  • c语言中向函数传递二维矩阵的方法
    在C语言中,向函数传递二维数组有几种方式,这主要取决于二维数组的大小是否已知。下面是几种常见的方式:  1)如果二维数组的大小已知,那么你可以在函数参数中直接指定数组的大小。例如: voidfunc(intarr[10][10]){...} 在这个例子中,func函数接受一个10x10的二维数组作为参数......