保研机试训练Day-04

离散化 && 区间合并

Posted by Jeffzzc on March 23, 2025

大纲

离散化

思路:因为存储的下标实在太大了,如果直接开这么大的数组,根本不现实 有人可能会提出用哈希表,哈希表可以吗?答案也是不可以的,因为哈希表不能像离散化那样缩小数组的空间,导致我们可能需要从-e9遍历到1e9 本题使用离散化,离散化的本质,是映射,将间隔很大的点,映射到相邻的数组元素中。减少对空间的需求,也减少计算量。本文用于存储这个关系的数组是alls[N];特地说明下,为什么要开300000+10呢,因为提前考虑了前缀和的因素,加上了2*m个点,又因为怕出现数组越界,多加了10。什么时候会用完300000个空间呢,那就是无重复元素,外加n和m都是1e5次方。

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;

const int N = 300010;
int n,m;
int a[N],s[N];

vector<int> alls;
vector<PII> add,query;

int find(int x){
    int l=0,r=alls.size()-1;
    while(l<r){
        int mid = l + r >> 1;
        if(alls[mid] >= x){
            r = mid;
        }
        else{
            l = mid + 1;
        }
    }
    return r + 1;
}
int main(){
    cin>>n>>m;
    for(int i=0;i<n;i++){
        int x,c;
        cin>>x>>c;
        add.push_back({x,c});
  
        alls.push_back(x);
    }
    for(int i=0;i<m;i++){
        int 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){
        int x = find(item.first);
        a[x] += item.second;
    }
    for(int i=1;i<=alls.size();i++) s[i] = s[i-1] + a[i];
    for(auto item:query){
        int l = find(item.first),r = find(item.second);
        cout<<s[r]-s[l-1]<<endl;
    }
    return 0;
}


区间合并

给定一个长度为 n 的整数序列,请找出最长的不包含重复的数的连续区间,输出它的长度。

#include<bits/stdc++.h>
using namespace std;

typedef pair<int,int> PII;

int n;
vector<PII> nums,res;

int main(){
    int st=-2e9,ed=-2e9;
    cin>>n;
    while(n--){
        int l,r;
        cin>>l>>r;
        nums.push_back({l,r});
    }
    sort(nums.begin(),nums.end());
    for(auto num:nums){
        if(ed<num.first){
            if(ed!=-2e9) res.push_back({st,ed});
            st=num.first,ed=num.second;
        }
        else if(ed<num.second) ed = num.second;
    }
    res.push_back({st,ed});
    cout<<res.size()<<endl;
    return 0;
}