[分治][Trie][prufer数列] 51Nod 1601 完全图的最小生成树计数

【数据结构】求最小生成树的权值之和——Prim算法 题源: 北航14级6系数据结构课第四次作业 【问题描述】  已知含有n个顶点的带权连通无向图,采用邻接矩阵存储,邻接矩阵以三元组的形式给出,只给出不包括主对角线元素在内的下三角形部分的元素,且不包括不相邻的顶点对。求该连通图的最小生成树的权值 【输入形式】  第一行给出结点个数n和三元组的个数count,以下每行给出一个三元组,数之间用空格隔开。(注意这里顶点的序号是从1到n, 阅读详情

SolutionSolution

考虑从高位到低位枚举。
显然是把相同的放在一边,不同的找到权值最小的连边,这个可以TrieTrie。
这样分治下去,最后得到一个没有限制的联通块,贡献就是sizesize−2sizesize−2。
因为偷懒写了vectorvector,还必须得预处理nn−2nn−2这样的东西qwq。。跑得巨慢。。
复杂度是O(nlog2w)O(nlog2⁡w)。
如果TrieTrie和分治一起写的话可能是可以O(nlogw)O(nlog⁡w)的啦。。

#include <bits/stdc++.h>
#define show(x) cerr << #x << " = " << x << endl
using namespace std;

typedef long long ll;
typedef pair<int, int> pairs;
const int N = 101010;
const int M = 3030303;
const int K = 30;
const int MOD = 1000000007;

inline char get(void) {
    static char buf[100000], *S = buf, *T = buf;
    if (S == T) {
        T = (S = buf) + fread(buf, 1, 100000, stdin);
        if (S == T) return EOF;
    }
    return *S++;
}
template<typename T>
inline void read(T &x) {
    static char c; x = 0; int sgn = 0;
    for (c = get(); c < '0' || c > '9'; c = get()) if (c == '-') sgn = 1;
    for (; c >= '0' && c <= '9'; c = get()) x = x * 10 + c - '0';
    if (sgn) x = -x;
}

int ch[M][2];
int sz[M];
int tcnt, root;
ll val;
int cnt;
int n;
int pwn[N];
vector<int> a;

inline pairs operator ^(int x, pairs y) {
    return pairs(x ^ y.first, y.second);
}

inline int pwr(int a, int b) {
    int c = 1;
    while (b) {
        if (b & 1) c = (ll)c * a % MOD;
        b >>= 1; a = (ll)a * a % MOD;
    }
    return c;
}
inline void init(void) {
    tcnt = root = 1;
}
inline void insert(int u, int x) {
    ++sz[u];
    for (int i = K; ~i; i--) {
        int &v = ch[u][x >> i & 1];
        if (v == 0) v = ++tcnt;
        u = v; ++sz[u];
    }
}
inline pairs query(int u, int x, int d) {
    if (d < 0) return pairs(0, sz[u]);
    int y = x >> d & 1;
    if (ch[u][y]) return query(ch[u][y], x, d - 1);
    return (1 << d) ^ query(ch[u][y ^ 1], x, d - 1);
}
inline void watch(vector<int> x) {
    for (int u: x) cerr << u << ' ';
    cerr << endl;
}
inline void divAndConq(int u, vector<int> &b, int d) {
    vector<int> b0, b1;
    if (u == 0) return;
    if (d < 0) {
        int n = b.size();
        if (n >= 2) cnt = (ll)cnt * pwn[n] % MOD;
        return;
    }
    b0.clear(); b1.clear();
    for (int x: b)
        if (x >> d & 1) b1.push_back(x);
        else b0.push_back(x);
    //watch(b0); watch(b1);
    //cerr << b0.size() << ' ' << b1.size() << endl;
    ll w = 1ll << 60, c;
    if (b0.size() < b1.size()) {
        if (b0.size() == 0) w = 0, c = 1;
        for (int x: b0) {
            pairs res = (1 << d) ^ query(ch[u][1], x, d - 1);
            if (res.first == w) {
                c += res.second;
            } else if (res.first < w) {
                w = res.first;
                c = res.second;
            }
        }
    } else {
        if (b1.size() == 0) w = 0, c = 1;
        for (int x: b1) {
            pairs res = (1 << d) ^ query(ch[u][0], x, d - 1);
            if (res.first == w) {
                c += res.second;
            } else if (res.first < w) {
                w = res.first;
                c = res.second;
            }
        }
    }
    val += w; cnt = (ll)cnt * c % MOD;
    divAndConq(ch[u][0], b0, d - 1);
    divAndConq(ch[u][1], b1, d - 1);
}

int main(void) {
    freopen("1.in", "r", stdin);
    freopen("1.out", "w", stdout);
    read(n); a.resize(n); init();
    for (int i = 2; i <= n; i++)
        pwn[i] = pow(i, i - 2);
    val = 0; cnt = 1;
    for (int i = 0; i < n; i++) {
        read(a[i]);
        insert(root, a[i]);
    }
    divAndConq(root, a, K);
    printf("%lld\n%d\n", val, cnt);
    return 0;
}
用贪心算法设计策略设计出构造最小生成树的有效算法 用贪心算法设计策略设计出构造最小生成树的有效算法krukal算法实现C语言 立即下载

相关推荐

最小生成树计数结题报告与代码

最小生成树计数的详细解题报告与C++代码~ 利用矩阵~

51Nod 1601 完全图的最小生成树计数-异或为边权

题目链接:http://www.51nod.com/Challenge/Problem.html#problemId=1601 题目大意: 思路: 这是一张完全图,并且边的权值是由点的权值xor得到的,所以我们考虑贪心的思想,考虑kruskal的过程选取最小的边把两个连通块合并,所以我们可以模仿kruskal的过程,倒着做kruskal,设定当前的最高位为d,我们把点集分为两个集合,s集合代表...

H_ang的博客 413

Unity调用手机摄像头避坑指南:从权限检测到自动对焦问题解决

本文深入解析了Unity移动端集成手机摄像头时遇到的权限、对焦与性能等核心难题。针对权限管理,提供了健壮的原生接口调用方案;针对自动对焦模糊问题,详细对比了原生插件与第三方插件两种解决路径;并分享了分辨率选择、数据处理及功耗控制等关键性能优化技巧,帮助开发者构建稳定高效的摄像头功能。

weixin_29007243的博客 470

牛客多校5 - Graph(字典树+分治求最小生成树)

题目链接:点击查看 题目大意:给出一棵树,每条边都有一个权值,每次操作可以删除任意一条边或者增加任意权值的一条边,现在可以执行数次操作,不过任何时间都要满足以下两个条件: n 个点互相连通 所有环的权值异或和为 0 求数次操作后图上边权之和的最小值 题目分析:将题意转换一下就可以转换为经典问题:完全图上的最小生成树,给出 n 个点,每个点都有权值 a[ i ] ,每条边的权值为 a[ i ] ^ a[ j ] 现在需要求最小生成树 这个题目只需要 dfs 跑一遍就可以转换为上述问题了,这里不多赘述

Falcon的博客 1407

ESD放电路径分析

当金属外壳接地情况下,大部分外部干扰信号将会通过外壳,外壳到接地点,再由接地点回到干扰信号的地,实现干扰信号的回流,这点不仅仅适用于​ESD,对于其他的RI类干扰,也同样适合。发现内部金属板跟外壳的搭接处存在较多的缝隙点,该缝隙点对于频率较高的信号能够实现较为理想的回流,但是对于频率没有那么高的信号,则较难以实现回流,我们尝试将这些缝隙用铜箔包裹住,充分降低该金属板跟外壳的接触阻抗​。我们分析,路径3其实是不期望的路径,我们最期望的路径是1,或者2的内部金属部件跟外壳良好接触情况下的路径。

domen_pan的博客 2227

MATLAB去雾算法实战:5种经典方法对比+1种改进方案(附完整源码)

本文详细对比了MATLAB中5种经典去雾算法(包括暗通道先验、多尺度Retinex等)的实现效果,并提出一种创新的自适应融合改进方案。通过完整的源码展示和性能对比,帮助开发者掌握图像去雾的核心技术,提升计算机视觉应用中的图像质量。特别针对去雾算法中的光晕效应问题,给出了工程实践中的优化技巧。

weixin_26801149的博客 412

面向问题求解的高级程序设计:(八)最小生成树

系列文章目录 面向问题求解的高级程序设计: (一)枚举 (二)查找 (三)贪心算法 (四)搜索 (五)分治与递归 (六)动态规划 (七)最短路 (八)最小生成树 文章目录系列文章目录一、简介二、例题1.模板题2.模板题再续3.另一道模板题4.复杂一点的模板题5.模板题变形6.霓虹模板题总结 一、简介 二、例题 1.模板题 2.模板题再续 3.另一道模板题 4.复杂一点的模板题 5.模板题变形 6.霓虹模板题 总结 提示:这里对文章进行总结: 例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas

weixin_53312629的博客 427

Arduino for ESP32-----ESP-NOW介绍及使用

ESP-NOWESP-NOW介绍ESP-NOW支持以下特性ESP-NOW技术也存在以下局限性获取ESP32的MAC地址ESP-NOW单向通信(One-way communication)ESP32单板间的双向通信一对多通信(一发多收)一对多通信(多发一收) ESP-NOW介绍 ESP-NOW是一种由Espressif开发的协议,可以让多个设备在不使用Wi-Fi的情况下相互通信。该协议类似于低功耗的2.4GHz无线连接。设备之间的配对需要在通信之前完成。配对完成后,连接是安全的、点对点的,不需要握手。这意味着

Better_man1的博客 2万+

51Nod1601 完全图的最小生成树计数

题目看这里 这个题好像在哪里做过。。。但是翻不到 基本思想:在最高位不同的两个集合里只能有一条边相连 我们可以用trie来做,每次到一个节点,就在他的两个儿子里找xor值最小的加到答案里 若有超过2个权值相同的点时,计算方案的方法为x^(x-2),这个是完全图的生成树个数公式 无...

dianning8393的博客 254

SpringBoot项目搭建

SpringBoot项目搭建

私信可回答各种问题~ 1020

YOLOv12改进策略【注意力机制篇】| 2024 PPA 并行补丁感知注意模块,提高小目标关注度(二次改进A2C2f)

本文记录的是利用改进检测精度,详细说明了优化原因,注意事项等。原论文在红外小目标检测任务中,小目标在多次下采样操作中容易丢失关键信息。通过替代编码器和解码器基本组件中的传统卷积操作,更好地保留小目标的重要信息。HCF-Net: Hierarchical Context Fusion Network for Infrared Small Object Detection采用多分支特征提取策略,通过不同分支提取不同尺度和层次的特征。利用局部、全局和串行卷积分支,对输入特征张量进行处理。通过控制 patch si

Limiiiing的博客 1887

51nod 1601 完全图的最小生成树计数 字典树+最小生成树

题意 给定一个长度为n的数组a[1..n],有一幅完全图,满足(u,v)的边权为a[u] xor a[v] 求边权和最小的生成树,你需要输出边权和还有方案数对1e9+7取模的值 1&lt;=n&lt;=10^5 0&lt;=a[i]&lt;2^30 分析 根据异或的性质,我们可以从高位到低位贪心。对于当前位,我们可以把点集分为当前位是1和是0两部分,显然最优的连边方案是两个集合自成...

beginend 646

【Dify】36氪新闻热榜智能自动化采集与AI处理

本文介绍如何利用Dify等自动化工具实现36氪新闻热榜的智能采集与处理。通过HTTP请求节点获取数据,JSON解析节点结构化处理,AI处理节点生成智能摘要,最终格式化输出结果。工作流程包含数据获取、解析、AI摘要、文本整理和内容输出五个环节,支持批量化、定制化的新闻处理需求。该方案适用于行业监测、内容创作、舆情管理等场景,显著提升信息获取效率,实现"所需即得"的自动化新闻服务。系统采用OpenAI GPT和Dify API作为核心模型,无需复杂人工干预即可完成全流程处理。

Mr数据杨 598

基于Python+Vue的校园食堂点餐系统设计与实现全解析

数据库设计是Web项目开发的基石,尤其对于前后端分离架构,合理的表结构直接决定系统的可扩展性与维护成本。以关系型数据库为核心,通过订单主表与明细表的拆分,能够有效解决一对多数据建模难题,同时快照字段的设计保障了历史数据的准确性。前后端分离作为现代Web开发的主流模式,后端提供JSON接口,前端负责交互渲染,两者通过HTTP协议通信,提升了开发效率与系统灵活性。在具体业务场景中,校园食堂点餐系统覆盖了用户认证、商品管理、购物车、订单流转等典型模块,非常适合用于学习完整工程实践。本文基于Python Flask

weixin_34050005的博客 419

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

[题集]图论

生成树 MST?Kruskal过程:贪心、重构树 prufer序列:一般树,森林,有根树,用于DP或者打暴力 Matrix-Tree定理:给定图求生成树个数,邻接矩阵数字表示边权 多次求MST或者多次加边等等:考虑缩点 一些图的问题:找到生成树处理(如Tarjan的dfs树,支配树,最短路树) 1.[Ctsc2014]图的分割 考虑Kruskal的过程,发现恰好可以直接贪心! 2...

weixin_34206899的博客 267

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

51nod 1601 完全图的最小生成树计数 Trie+kruskal

题意:给定一个长度为n的数组a[1..n],有一幅完全图,满足(u,v)的边权为a[u] xor a[v] 求边权和最小的生成树,你需要输出边权和还有方案数对1e9+7取模的值。由于边权是xor得到,容易想到用trie统计。。 按照当前最高位0/1将当前区间内的点分成两个部分s/t,那么答案肯定是s的最小生成树+t的最小生成树+s-t的最小边,s-t最小边用trie统计,最小生成树递归处理。

老臣 1790

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

1601 完全图的最小生成树计数

题意 给定一个长度为n的数组a[1..n],有一幅完全图,满足(u,v)的边权为a[u] xor a[v] 求边权和最小的生成树,你需要输出边权和还有方案数对1e9+7取模的值 题解 考虑贪心 先建立字典树 对于字典树上的每一个点,他子树的生成树肯定是 s1的生成树+s2的生成树+s1到s2的最小边 前两个都是子问题 s1到s2的最小边可以用启发式合并来解决 CODE: ...

OZY的博客 491

51nod 算法马拉松22 完全图的最小生成树计数 【Trie树+图论】

题目连接:http://www.51nod.com/contest/problem.html#!problemId=1601——————————————————————————. 完全图的最小生成树计数 SkyDec (命题人) 基准时间限制:1 秒 空间限制:131072 KB 分值: 160给定一个长度为n的数组a[1..n],有一幅完全图,满足(u,v)的边权为a[u] xor a[v

Tabris的博客 1443

BZOJ 1211 树的计数 Prufer序列

一个节点在prufer数列中出现的次数是这个节点的度数减一。 这样我们就知道这个数列中有哪些数了,因为一个prufer数列唯一对应一颗树。然后问题就变成了求有多少种prufer数列。又因为我们知道了元素种类与出现次数。于是问题就变成了求一个有重复元素的全排列。 因为n最大有150.所以分解一下质因数就好了。

嗯。 549

【贪心】【分治】xor最小生成树

【题目描述】 给你一张无向完全图,每个点有一个ai, i号点和j号点之间的边权为aixoraja_{i} xor a_{j}ai​xoraj​,求最小生成树。 (n<=10000) 【思路】 这道题显然不能把所有边拿来排序,这样复杂度就炸了。所以我们只能考虑从异或的性质入手。异或满足不同为1,相同为0.我们自然希望0越多越好,1越少越好,尤其是高位。所以我们就有了一个贪心的策略:从高到低枚举...

weixin_44111457的博客 624

最小生成树及其求解算法

最小生成树 图论中,树是图的一种特殊形式,它的众多性质中有两个是求解最小生成树的Prim算法和Kruskal算法的基础: (1)用一条边连接树中的任意两个顶点都会产生一个新的环; (2)从树中删去一条边将会得到两棵独立的树。 无权图中的边只是单纯的作为联系两个顶点的抽象概念,而带权图(也称加权图)中为边增加了权重,使得顶点之间的路径形式变得更丰富多样。图的生成树是它的一棵含有其所有顶点的无...

程序人生 2263

51nod 1835 完全图

原题链接. 比赛时我怎么都不会做这一题。旁边人表过了。显然的状态是fi,jf_{i,j}表示用了序号前i个,有j块的方案数。显然可以枚举第i个放的块的大小来转移。fi,j=∑i−(j−1)k=1fi−k,k−1∗fk−1,1∗Ck−1i−1f_{i,j} =\sum_{k=1}^{i-(j-1)}f_{i-k,k-1}*f_{k-1,1}*C_{i-1}^{k-1}这条方程神奇之处在于自我调用fk

Cold_Chair的博客 670

[JSOI2008]最小生成树计数

[JSOI2008]最小生成树计数 Time Limit: 1 Sec Memory Limit: 162 MB Description   现在给出了一个简单无向加权图。你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的 最小生成树。(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的)。由于不同的最小生 成树可能很多,所以你只需要输出方案数对3101...

lvmaooi的博客 617

LOJ 6062 [Hall定理]

Hall定理:设M(S)M(S)为与SS中的点相连的点集,一个二分图(U,V)(|U|≤|V|)(U,V)(|U|\le|V|)存在完备匹配,当且仅当满足对于任意点集x∈Ux∈U,都有|M(X)|≥|X||M(X)|\ge|X|。DescriptionDescription给出一个长度为nn的数列{aia_i}和一个长度为mm的数列{bib_i},求{aia_i}有多少个长度为mm的连续子数列能与{

Vectorxj的博客 1564
上一篇: [DP][分治] 51Nod 1934 受限制的排列
下一篇: [DP][容斥原理] ARC064 F - Rotated Palindromes
Vectorxj
博客等级 码龄11年 35粉丝 231原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值