离散化&前缀和 学习笔记

什么是离散化?

把无穷大集合中的若干个元素映射为有限集合,以便于统计的方法;

在不改变数据相对大小的情况下,对数据进行相应的缩小。

例:(1)处理前:1,23,114514,999.

我们按从小到大进行标号。1标为0,23标为1,999标为2,114514标为3.

处理后:0,1,3,2.

(2)处理前:{100,200} ,{20,50000},{1,400};

同样方法处理。

处理后:{2,3}  {1,5 }  {0,4 }

离线化前提:1.问题只涉及有限个数值。

                      2.问题与数值的绝对大小无关,只与相对顺序有关。

在csdn曹老师阿看到了一个很好就能解释的例子,借用一下

举个例子,如果一个坐标轴很长(>1e10),给你1e4个坐标,询问某一个点,坐标比它小的点有多少。

很容易就知道,对于1e4个点,我们不必把他们在坐标轴上的位置都表示出来,因为我们比较有多少比它小的话,只需要知道他们之间的相对大小就可以,而不是绝对大小,这,就需要离散化。

如何进行离散化

函数:unique                sort

unique的作用是去重,但是去重前要先进行排序,保证重复元素相邻

sort(b,b+n);

m = unique(b,b+n) - b;

m代表的是去重后的元素个数

返回值:背后值得第一个元素的“首地址”

比如排序完数组里为 0 1 6677 123456789 6677 6677 123456789

那么此时的返回值就为标红的6677,-b的原因是删去返回值。

注意:1.unique执行的不是删除重复项而是用不重复的元素替换了重复元素。

一种常用的离散化去重方法:

1.排序

2.去重

3.索引元素离散化后对应的值

 -b的作用参照上面

什么是前缀和

为什么要用前缀和

 

 即把很多次加法转换为一次减法,降低时间复杂度

#include <bits/stdc++.h>

using namespace std;

const int N=1e6 + 10;
long long sum[N],a[N];

int main()
{
	long long n;
	long long l,r;
	long long ans;
	scanf("%lld",&n);
	//预处理 
	for(int i=1;i<=n;i++)
	{
		sum[i]=sum[i-1]+a[i];
	} 
//--------------------------------
	//求值
	scanf("%lld %lld",&l,&r);
	ans=0;
	ans= sum[r] - sum[l-1];//前r项和减去前l-1项和 
	 
}

二维前缀和

比如我们要去sum[x][y]即求下图有颜色的区域可以用绿色区域加上粉色区域减去橙色区域再加上红色区域

其中绿色区域=图上可见绿色区域+橙色区域

同理粉色区域=图上可见粉色区域+橙色区域

 

 同理我们可以求各个区域的和

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值