首页 > 其他分享 >差分离散化问题

差分离散化问题

时间:2024-07-09 17:29:57浏览次数:9  
标签:问题 端点 int 差分 离散 数组 区间

火烧赤壁

题目背景

曹操平定北方以后,公元 208 年,率领大军南下,进攻刘表。他的人马还没有到荆州,刘表已经病死。他的儿子刘琮听到曹军声势浩大,吓破了胆,先派人求降了。

孙权任命周瑜为都督,拨给他三万水军,叫他同刘备协力抵抗曹操。

隆冬的十一月,天气突然回暖,刮起了东南风。

没想到东吴船队离开北岸大约二里距离,前面十条大船突然同时起火。火借风势,风助火威。十条火船,好比十条火龙一样,闯进曹军水寨。那里的船舰,都挤在一起,又躲不开,很快地都烧起来。一眨眼工夫,已经烧成一片火海。

曹操气急败坏的把你找来,要你钻入火海把连环线上着火的船只的长度统计出来!

题目描述

给定每个起火部分的起点和终点,请你求出燃烧位置的长度之和。

输入格式

第一行一个整数,表示起火的信息条数 \(n\)。
接下来 \(n\) 行,每行两个整数 \(a, b\),表示一个着火位置的起点和终点(注意:左闭右开)。

输出格式

输出一行一个整数表示答案。

样例 #1

样例输入 #1

3
-1 1
5 11
2 9

样例输出 #1

11

提示

数据规模与约定

对于全部的测试点,保证 \(1 \leq n \leq 2 \times 10^4\),\(-2^{31} \leq a < b \lt 2^{31}\),且答案小于 \(2^{31}\)。

解题思路

首先发现,数据量较少,数据区间很大,所以考虑使用离散化操作。

每次操作都是针对一个区间进行,所以我们可以考虑使用差分来进行区域操作。

这时会遇到一些问题。

由于题目中给出的区间为 左闭右开,因此如果存在两个区间相邻的情况(不叠加),所以右端点的操作应该是\(b[i]-=1\)而不是\(b[i+1]-=1\)。

我们假设有两个区间\([1,20)\)和\([45,400)\)这时可以发现,我们离散化之后得到的差分数组的前缀和为\(1,0,1,0\)。此时如果我们直接将这个数组映射回原数组,可以发现我们无法得到有效的区间。

所以,我们不可以这么直接的将前缀和数组映射回原数组,应该考虑这个经过离散化后的数组每一个值表示的都是一段区间。如果中间不存在零的出现,就说明这个映射区间是连续的,可以直接映射回去求区间长度即可(这个数组是有序的,如果是0,一定存在没有被覆盖到的地方)。

如果出现了间断,那么我们就应把数组中的每一个点拿出来单独考虑。如果是1,就说明这个端点(不难发现我们离散化之后获得的是很多个区间的端点)到下一个端点之间的区间是没有断点的,我们就可以把前缀和数组的这个端点单独拿出来考虑,映射回原数组体现出来的就是一个单独的小区间,不考虑与其它区间的关系,则有\(arr[i+1]-arr[i]\)可以作为有效区间被我们统计,之后再考虑下一个端点。如果是0,则为间断区间,跳过即可。

不难发现,题目作者为了简化问题,特地选取的开区间,不存在需要我们考虑可以取到右端点的两个间断区间。如果我们假设题目此时取到的为闭区间,则我们仍然需要以左闭右开的形式进行差分,避免选取中间的间断区间。

#include<bits/stdc++.h>
using namespace std;
const int N = 20200*2;
typedef pair<long long,long long>PII;
vector<long long>alls;
vector<PII>pos;
int n;
long long ans,sum;
int a[N],b[N];
int find(int x){
	int l=-1,r=alls.size();
	while(l+1!=r){
		int mid=l+((r-l)>>1);
		if(alls[mid]<x)l=mid;
		else r=mid;
	}
	return r+1;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		long long l,r;
		scanf("%lld %lld",&l,&r);
		alls.push_back(l);
		alls.push_back(r);
		pos.push_back({l,r});
	}
	sort(alls.begin(),alls.end());//映射操作
	alls.erase(unique(alls.begin(),alls.end()),alls.end());//去重操作
	for(auto item:pos){
		int l=find(item.first),r=find(item.second);
		a[l]=item.first,a[r]=item.second;
		b[l]+=1,b[r]-=1;//b[l]+=1,b[r+1]-=1;
	}
	for (int i = 1; i <= alls.size(); i++) {
		sum += b[i];//这个拿出去也一样
		if (sum > 0) ans += a[i + 1] - a[i];
	}

//	for(int i=1;i<=alls.size()+1;i++){
//		b[i]+=b[i-1];
//	}
//	for(int i=1;i<=alls.size();i++){
//		cout<<b[i]<<' ';
//	}cout<<endl;
//	long long l,r;
//	for(int i=1;i<=alls.size();i++){
//		if(b[i]>0&&b[i-1]<=0)l=i;
//		if(b[i]>0&&b[i+1]<=0){
//			r=i;
//			cout<<r<<' '<<l<<endl;
//			ans+=a[r]-a[l]+1;
//		}
//	}
	cout<<ans<<endl;
	return 0;
}

标签:问题,端点,int,差分,离散,数组,区间
From: https://www.cnblogs.com/haihaichibaola/p/18292406

相关文章

  • Redis三大缓存问题:缓存穿透、缓存击穿、缓存雪崩的场景以及解决方法
    文章目录都是缓存惹的祸缓存穿透场景描述解决方法缓存键同时失效1.过期时间随机化2.使用多级缓存3.缓存预热4.加互斥锁缓存中间件故障1.服务熔断-Java示例2.构建Redis集群注意事项缓存击穿场景描述解决方法1.加互斥锁(MutexLock)2.永久缓存热点数据注意事......
  • 关于Vmamba模块安装SSM包环境问题
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档@TOC关于Vmamba模块安装SSM包环境问题前言提示:这里可以添加本文要记录的大概内容:最近在服务器上安装VMamba环境,记录一下解决问题的方法。因为网上租的服务器他的CUDA不在系统的环境变量当中,所以,下载了ca......
  • 北京市企业科技研究开发机构认定常见问题
    在申请北京市企业科技研究开发机构认定的过程中,众多企业常面临一系列共性问题,这些问题往往关乎申报资格、材料准备、评审标准及后续支持政策等关键环节。比如,如何界定“研究开发费用占销售收入的比例”?研发机构的组织结构与职能定位应如何设置以符合认定要求?已提交的材料如何......
  • electron 跨域/CSP问题
    请求报错:Refusedtoconnectto'http://127.0.0.1:8000/get?name=kv-grpc'becauseitviolatesthefollowingContentSecurityPolicydirective:"default-src'self'".Notethat'connect-src'wasnotexplicitlyset,so'......
  • QPushButton的checked和pressed样式设置无效是因为优先级问题
    设置QPushButton想要设置pressed状态的图标,但是尝试了很多次都没有效果,原来是按照优先级来的,位置越往下优先级越高,hover状态时在最下面,所以鼠标在按钮上时,hover优先级最高,所以无论pressed还是checked都无法显示正确的图标,所以要调整下顺序; QPushButton{border-image:url......
  • c++临时对象导致的生命周期问题
    对象的生命周期是c++中非常重要的概念,它直接决定了你的程序是否正确以及是否存在安全问题。今天要说的临时变量导致的生命周期问题是非常常见的,很多时候没有一定经验甚至没法识别出来。光是我自己写、review、回答别人的问题就犯了或者看到了许许多多这类问题,所以我想有必要做个......
  • oracle登录常见问题
    常见问题问题一:bash:sqlplus:commandnotfound...sqlplus/assysdba 解决方法:出现这个情况就是环境变量没有设置好, 重新设置环境变量就可以了, 使用 su-l oracle 就没问题(每次重启服务器都要导入一遍) 问题一:用户名密码不对解决方法:切换为oracle用户......
  • Exchange被黑客利用做中继外发垃圾邮件问题分析
    近期有用户反馈有大量非本域的邮件从自家服务器发出,还成功投递出来了,不过不用担心,到我们服务商这边被识破,全部拦截下来。以下是用户自建服务器发出的垃圾邮件案例:以上信息只有ip是用户自建服务器的,发件人和邮件都非用户本人发送,可以看出域名都可以通过客户的服务器中继出来发送......
  • 挂 CSDN,老问题了,现在开始盗我源码不管了
    挂CSDN,老问题了,现在开始盗我源码不管了,希望没有倒霉蛋来买,买了也别找我,我不维护这个项目了!挂壁链接:https://download.csdn.net/download/weixin_44087733/89352970之前盗我文章,把我内置保护链接去掉,嵌广告事,我不挂你名不解决。好,挂出来好使了,我也没追究啥。现在轮到我源码了,虽......
  • 7 常见问题
    关于ssh连接一些常见的错误说明ERROR!tousethe'ssh'connectiontypewithpasswords,youmustinstallthesshpassprogram完整错误示例如下:root@ctnr:/etc/ansible#ansible'*.a32-168-1.*'-mpingctnr.a32-168-1.prod.yiz|FAILED!=>{"fail......