应用:
对于数据量比较小,但是数据范围比较大的题目,可以运用离散化来实现,因为开太大的数组也不现实
实现
思路:对于较大的数据范围可以进行映射到连续的数据数量,可以减少空间的使用和运算量,对于数据的储存肯呢个出现数据的重复,所以需要去重处理,对于离散化关键在于怎样处理映射和原数据之间的关系
映射处理
实现此对应的是用的二分,找到第一个大于等于x的位置
int find(ll x)
{
ll l=0,r=alls.size();
while(l<r)
{
ll mid=l+r >>1;
if(alls[mid]>=x)r=mid;
else l=mid+1;
}
return r+1;
}
返回r+1是保证映射是从1开始的
去重处理
alls.eares(unique(alls.begin(),alls.end()),alls.end());
对于存在重复数组a[100],unique(a.begin(),a.end());j将不重复的数据按照原来的相对位置排到前面,返回第一个重复的数据的位置,上述调用的c++的函数,也可以通过下面实现
对于int型的数据
int unique(int a[])
{
int c[Max],j=0;
for(int i=0;i<=l;i++)//l 数组a的长度
{
if(i==0||a[i-1]!=a[i])
c[j++]=a[i];
}
for(int i=0;i<j;i++)
a[i]=c[i];
return a+j;
}
完整实现
int a[Max];
vector<ll>alls;//所有要离散化的数
int find(ll x)
{
ll l=0,r=alls.size();
while(l<r)
{
ll mid=l+r >>1;
if(alls[mid]>=x)r=mid;
else l=mid+1;
}
return r+1;
}
int main()
{
int n;
for(int i=0;i<n;i++)
{
int x;
cin>>x;
alls.push_back(x);
}
//去重
sort(alls.begin(),alls.end());
alls.erase(unique(alls.begin(),alls.end()),alls.end());
}
典型例题
区间和
#include<bits/stdc++.h>
#define ll long long
#define PI 3.141592653589793
#define E 2.718281828459045
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define mem(a,b) memset(a,b,sizeof(a))
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define FO( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define lowbit(a) ((a)&-(a))
#define PII pair<ll ,ll >
#define ft first
#define sd second
typedef unsigned long long ull;
const ll mod=10007;
const ll INF=0x3f3f3f3f3f3f3f3f;
const ll Max=300010;
using namespace std;
ll t,n,m,k;
ll ans;
ll a[Max],s[Max];
vector<ll>alls;//所有要离散化的数
vector<PII>add,query;
/*queue<ll> q;
stack<ll> s;
//升序队列
priority_queue <int,vector<int>,greater<int> > q;
//降序队列
priority_queue <int,vector<int>,less<int> >q;*/
ll find(ll x)
{
ll l=0,r=alls.size();
while(l<r)
{
ll mid=l+r >>1;
if(alls[mid]>=x)r=mid;
else l=mid+1;
}
return r+1;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
for(ll i=0;i<n;i++)
{
ll x,c;
cin>>x>>c;
add.push_back({x,c});
alls.push_back(x);
}
for(int i=0;i<m;i++)
{
ll l,r;
cin>>l>>r;
query.push_back({l,r});
alls.push_back(l);
alls.push_back(r);
}
//去重
sort(alls.begin(),alls.end());
alls.erase(unique(alls.begin(),alls.end()),alls.end());
//处理插入
for(auto item:add)
{
ll x=find(item.first);
a[x]+=item.sd;
}
//预处理前缀和
for(ll i=1;i<=alls.size();i++)
s[i]=s[i-1]+a[i];
for(auto item:query)
{
ll l=find(item.ft),r=find(item.sd);
cout<<s[r]-s[l-1]<<endl;
}
return 0;
}