CodeForces 1045G AI robots(CDQ分治 + 树状数组 + 单调队列)_codeforces cdq-程序员宅基地

技术标签: 树状数组  CodeForces  ------------数据结构-----------  单调队列  ---------Online Judge--------  --------------分治--------------  CDQ分治  

 

 

大致题意:有很多个机器人,他们要相互交流有一些限制条件。首先是,两个人要相互能够能够看到;其次,两个人的智商的差不超过K。现在给出每个机器人的视力范围和他们的智商,现在问你总共有多少对机器人能够相互交流。

首先来看下总共有多少个限制条件。由于是要求双方都能够看到,所以显然是要按照视野半径去排序的。然后要求两个人的智商差要在一定的范围内的,所以也要按照智商去排序。另外还要跟自己的位置有关。根据这个,我们可以构造出分治的大致方法:首先按照半径去排序,半径大的在前面,因为这样如果后面的东西能够看到前面,那么前面的东西一定能看到后面,符合cdq分治前面更新后面的要求;然后分治的过程中归并排序按照智商的大小去排序,因为这样可以利用一些单调性,同时好确定智商差;最后就是用一个离散化的树状数组去维护每个位置的机器人数量。

前面和最后的都好说,关键是如何利用智商差去求能够相互看到的机器人的对数。这里我们用到了单调队列。由于是按照智商的大小来进行分治的。所以前一半和后一半已经是按照智商的大小排好序了的,所以说我们可以利用单调性。根据cdq分治的原则,前面一半去更新后面一半,所以我们考虑对于后一半的每个机器人,单独计算贡献。对于后一半的第i个机器人,我可以在前一半确定一个区间[j,k],在这个区间内的所有机器人与机器人i的智商差不超过K。把这个区间内的所有机器人添加到树状数组中,然后贡献就是机器人i视野范围内的机器人数目。然后再往后考虑后一半的其他机器人。由于前一半和后一半的智商是递减的,所以从i移动到i+1区间的移动只会单调往后移动,符合单调队列性质。这样前一半的每一个机器人只会进出队列各一次,对应加入和移出树状数组各一次。所以这个部分均摊的时间复杂度是O(NlogN)的,这个log来自树状数组。

如此我们就求出了合并的时候前面对后面产生的贡献。总的时间复杂度就是O(NlogNlogN)。具体见代码:

#include<bits/stdc++.h>
#define LL long long
#define N 100010

using namespace std;

struct node{int x,r,iq,L,R;} p[N],tmp[N];
int n,tot,K,x[N<<2],q[N]; LL ans=0;

struct BinaryIndexedTree
{
    int c[N<<2];

    inline void update(int x,int k)
    {
        x=min(x,tot);
        for(;x<=tot;x+=x&-x) c[x]+=k;
    }

    inline int getsum(int x)
    {
        int ans=0;
        for(;x>0;x-=x&-x) ans+=c[x];
        return ans;
    }

} BIT;

bool cmp1(node a,node b)
{
    return a.r>b.r;
}

bool cmp2(node a,node b)
{
    return a.iq>b.iq;
}

void cdq(int l,int r)
{
    if (l==r) return;
    int mid=(l+r)>>1;
    cdq(l,mid);
    cdq(mid+1,r);
    int h=0,t=0;
    for(int i=mid+1,j=l;i<=r;i++)
    {
        while(j<=mid&&p[j].iq-p[i].iq>K) j++;
        while(j<=mid&&abs(p[j].iq-p[i].iq)<=K)
        {
            BIT.update(p[j].x,1);
            q[t++]=j++;
        }
        while(h<t&&abs(p[q[h]].iq-p[i].iq)>K)
        {
            BIT.update(p[q[h]].x,-1);
            h++;
        }
        ans+=BIT.getsum(p[i].R)-BIT.getsum(p[i].L-1);
    }
    for(;h<t;h++) BIT.update(p[q[h]].x,-1);
    inplace_merge(p+l,p+mid+1,p+r+1,cmp2);
}

int main()
{
    scanf("%d%d",&n,&K);
    for(int i=1;i<=n;i++)
    {
        int X,Y,Z;
        scanf("%d%d%d",&X,&Y,&Z);
        p[i]=node{X,Y,Z,0,0};
        x[++tot]=X; x[++tot]=X-Y; x[++tot]=X+Y;
    }
    sort(x+1,x+tot+1);
    tot=unique(x+1,x+tot+1)-x-1;
    for(int i=1;i<=n;i++)
    {
        p[i].L=lower_bound(x+1,x+tot+1,p[i].x-p[i].r)-x;
        p[i].R=lower_bound(x+1,x+tot+1,p[i].x+p[i].r)-x;
        p[i].x=lower_bound(x+1,x+tot+1,p[i].x)-x;
    }
    sort(p+1,p+n+1,cmp1);
    cdq(1,n);
    printf("%lld\n",ans);
    return 0;
}

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u013534123/article/details/83241568

智能推荐

linux usb虚拟网卡(NCM)_linux usb ncm-程序员宅基地

文章浏览阅读6.6k次。1. kernel config<M>USB Gadget precomposed configurations<M>Ethernet Gadget (with CDC Ethernet support) <M>Network Control Model (NCM) support2. build modulesmake ARCH=arm64 CROSS_COMPILE=aar..._linux usb ncm

Struts 应用转移到 Struts 2-程序员宅基地

文章浏览阅读1.9k次。 翻译:SpringSide团队 转载请注明出处。有很多人都很熟悉 Struts, 无论是从项目中直接获得的实战经验还是从书中了解到的。我们这一系列文章,将通过一个由 Stuts 转移到 Struts2 简单的例子向大家展现Struts2的所有特征。 在我们开始这个例子之前,你需要去知道一点 Struts2的背景知识。 在第一部分的文章中,我们将介绍Struts2与Struts的核心

在Windows平台上安装MRTG流量监控软件_mrtg 下载-程序员宅基地

文章浏览阅读188次。打开MRTG软件包中的"MRTG.cfg"文件,该文件是MRTG的主配置文件。打开MRTG软件包中的"MRTG.cfg"文件,该文件是MRTG的主配置文件。确保将命令中的"C:\MRTG"替换为你的MRTG安装目录和配置文件路径,"community"替换为你的SNMP团体字符串,"device_ip"替换为目标设备的IP地址。确保将命令中的"C:\MRTG"替换为你的MRTG安装目录和配置文件路径,"community"替换为你的SNMP团体字符串,"device_ip"替换为目标设备的IP地址。_mrtg 下载

kaggle简单使用教程(代码查找.下载、项目建立.运行、参加比赛)_kaggle在线写代码-程序员宅基地

文章浏览阅读1w次,点赞7次,收藏35次。Kaggle机器学习竞赛、托管数据库、编写和分享代码_kaggle在线写代码

network.service - LSB: Bring up/down networking_network.service - lsb: bring up/down networking lo-程序员宅基地

文章浏览阅读3.1k次,点赞11次,收藏14次。CentOS7突然连接不了网络,使用systemctl status network后报如下错误network.service - LSB: Bring up/down networkingLoaded: loaded (/etc/rc.d/init.d/network; bad; vendor preset: disabled)Active: failed (Result: exit-code)【解决方案】停止NetworkManager并取消开机启动chkconfig NetworkMan_network.service - lsb: bring up/down networking loaded: loaded (/etc/rc.d/in

随便推点

OpenCV图像梯度_opencv 计算梯度图像-程序员宅基地

文章浏览阅读1.7k次。目标在本章中,我们将学习:寻找图像梯度、边缘等 我们将看到以下职能:cv2.sobel(), cv2.scharr(), cv2.Laplacian()等理论OpenCV提供三种类型的梯度滤波器或高通滤波器,Sobel、Scharr和Laplacian.我们会看到他们中的每一个。1.Sobel和Scharr衍生物¶Sobel算子是一种联合高斯平滑加微分运算,具有更强的..._opencv 计算梯度图像

flutter 聊天界面+表情图片_flutter表情包插件-程序员宅基地

文章浏览阅读2.6k次。网上找了找 零零碎碎有一些文章 没找到一个整体的 自己做完记录一下 防止忘了大体就是这样聊天气泡用的是https://blog.csdn.net/oterminator12/article/details/105790961这个文章看到的然后表情用的是https://blog.csdn.net/qq_36676433/article/details/104756685这个文章看到的整体结构及底部输入/表情选择部分body下的结构主要为最外层Column,然后聊天部分用F..._flutter表情包插件

win10应用:便签 商店 xbox等打不开,报错0x800704cf_xbox0x800704cf错误代码-程序员宅基地

文章浏览阅读2.8k次,点赞3次,收藏2次。登录便签,一直报错:执行此操作需要Internet,0x800704cf。笔者网络是没有问题的,其它程序可以正常访问。解决方法关闭代理1.Win+R打开运行,输入 inetcpl.cpl 打开internet选项界面2.切换到[连接]选项,点击局域网设置。红色框选处的两个勾取消。笔者上述配置后即可解决问题。如若还不能解决,试试下面这个方法设置DNS服务器地址,首选设置为4.2.2.1 备用设置为4.2.2.2..._xbox0x800704cf错误代码

conda命令克隆(复制)环境_conda clone-程序员宅基地

文章浏览阅读8.9w次,点赞55次,收藏138次。在服务器上想要使用别人搭好的环境,但是又怕自己对环境的修改更新会影响他人的使用,这个时候可以使用conda命令进行复制环境。首先假设已经安装了Anaconda。根据已有环境名复制生成新的环境假设已有环境名为A,需要生成的环境名为B:conda create -n B --clone A根据已有环境路径复制生成新的环境假设已有环境路径为D:\A,需要生成的新的环境名为B:conda ..._conda clone

Enterprise:使用 MySQL connector 同步 MySQL 数据到 Elasticsearch_mysql connectors-程序员宅基地

文章浏览阅读3.1k次。在本文中,我们非常详细地描述如何使用 MySQL connector 来同步 MySQL 和 Elasticsearch 的索引。它使用起来非常方便。如果大家对 Logstash 很熟悉的话,请参阅我之前的文章 “Elastic:开发者上手指南” 中的 “数据库数据同步章节。我们还可以使用 Pipeline 对数据进行清洗。这个就不做展示了。_mysql connectors

HttpClientUtils工具类-程序员宅基地

文章浏览阅读1.5k次。HttpClientUtils工具类。_httpclientutils