201812-3 CIDR合并

本文介绍了一种CIDR(无类别域间路由)合并的方法,旨在减少IP前缀列表,通过排序、逐步合并及同级合并三个步骤实现。在第二步中,通过比较相邻元素的匹配集关系进行剔除;在第三步,针对前缀长度相同的元素,创建新前缀并检查合法性。由于时间复杂度要求,同级合并部分需使用链表优化以避免超时。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

201812-3 CIDR合并

题解思路

计算包含IP前缀数目最少的等价前缀列表
第一步:排序
将所有IP前缀进行排序,以其IP地址为第一关键字,以前缀长度为第二关键字从小到大排序,形成一个列表。
第二步:从小到大合并
从头到尾扫描该列表,依次考虑其相邻的两个元素a,b:如果b的匹配集是a的匹配集的子集,则将b从列表中移除。如果b后仍有元素c,则此时a与c变为相邻的元素,应当继续考虑这对新的相邻元素,直到a的下一个元素不能被移除。然后继续依次处理列表中接下来的相邻元素。
可以证明,在此躺扫描结束之后,列表中不会存在任何两个元素a,b使得b的匹配集是a的匹配集的子集。
第三步:同级合并
从头到尾扫描该列表,依次考虑其相邻的两个元素a,b:如果a与b的前缀长度相同,则设a’为一个新的IP前缀,其IP地址与a相同,而前缀长度比a少1。如果a’合法且a的匹配集与b的匹配集的并集等于a’的匹配集,则将a与b从列表中移除,并将a’插入到列表中原来a,b的位置。与上一步不同的是,如果a’之前存在元素,则接下来应当从a’的前一个元素开始考虑;否则继续从a’开始考虑。

由于这道题对时间卡得紧,需要在同级合并那里使用链表优化,不然会超时

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;
typedef long long ll;
const int N=1e6+10;
long long P[34]; //保存2的幂次 P[i]=2^(33-i)

struct IP
{
    ll s;
    int len;
    bool operator < (const IP &u) const
    {
        if(s<u.s) return true;
        else if(s>u.s) return f
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值