【矩阵乘法】生成树计数(luogu 2109/NOI 2007)

生成树计数

luogu 2109

题目大意

有n个排成一列的点,把距离不超过k的点之间连边,问这个图的生成树个数

输入样例

3 5

输出样例

75

样例说明

样例对应的图如下:
在这里插入图片描述

数据范围

在这里插入图片描述

解题思路

因为n十分大,不能直接2^m暴力枚举(m为总边数)
k十分小,可以从k入手
考虑到对某个点有贡献的只有前k个点
我们可以设状态表示前k个点的连接情况(即那几个点连在了一起)
状态如果直接用k位数表示肯定不行
考虑除掉无用状态
对于着k个数,如果前面有和它相连的点,那么这个点的数值等于和它相连的点的数值,如果没有,则它的数值等于前k个数中最大数值+1
例如:
k=5,1和3相连,2和5相连
则表示出来的状态为12132
s1=++ws_1=++ws1=++w
s2=++ws_2=++ws2=++w
s3=s1s_3=s_1s3=s1
s4=++ws_4=++ws4=++w
s5=s2s_5=s_2s5=s2
得出状态后,我们输出总装台数,k=5时竟只有52种!
用一个数组给各个状态存一下新的编号(52种中的第几种)
然后考虑状态之间的转移
对于所有用的状态,2k2^k2k枚举第k+1k+1k+1个点和kkk个点是否连边
使其满足以下条件
1.不连成环(即数值相同的点最多连一个,不然会形成环)
2.保证第1个点要和2∼k+12\sim k+12k+1个点中的一个相连(要么和k+1k+1k+1相连,要么和2∼k2\sim k2k个点中某个点的数值相等)
得出状态后通过前面的计算方法,把新状态的编号求出来,然后在矩阵中连起来
得到转移矩阵后,就可以用矩阵乘法快速得出n个点的结果了

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define wyc 65521
using namespace std;
ll n, k, w, ww, s[10], ss[10], fa[10], p[100000];
struct matrix
{ll n, m, a[100][100];matrix operator *(const matrix &b) const{matrix c;c.n = n;c.m = b.m;for (int i = 1; i <= c.n; ++i)for (int j = 1; j <= c.m; ++j)c.a[i][j] = 0;for (int i = 1; i <= c.n; ++i)for (int k = 1; k <= m; ++k)for (int j = 1; j <= c.m; ++j)c.a[i][j] = (c.a[i][j] + a[i][k] * b.a[k][j] % wyc) % wyc;return c;}
}A, B;
void dfs1(ll x, ll y, ll z)
{if (x > k){p[z] = ++w;//新编号ll num = 1, g = 0;for (int i = 1; i <= k; ++i){g = 1;for (int j = 1; j <= s[i] - 2; ++j)//题目说明中n个点的完全图生成树个数为n^(n-2)g = g * s[i];num = num * g;//各种种数相乘}A.a[1][w] = num;//计入初始矩阵return;}for (int i = 1; i <= y; ++i){s[i]++;//这个数值的数+1dfs1(x + 1, y, z * 10 + i);//和前面已有的点相连s[i]--;}s[y + 1]++;//新的数值dfs1(x + 1, y + 1, z * 10 + y + 1);//不相连s[y + 1]--;return;
}
ll find(ll x)
{return x == fa[x]?x:find(fa[x]);//并查集
}
void pp(ll x, ll y)
{if (x > k){ll num = 0, ww = 0;memset(ss, 0, sizeof(ss));for (int i = 2; i <= k + 1; ++i){ll g = find(i);if (!ss[g]) ss[g] = ++ww;//没有相连的就新加一个数值num = num * 10 + ss[g];//用十进制存起来}if (ss[find(1)]) B.a[p[y]][p[num]]++;//第一个数有被加到,那就连接状态return;}ll g = find(k + 1), gg = find(x);if (gg != g)//暂未相连{fa[g] = gg;//连接pp(x + 1, y);fa[g] = g;//没有路径压缩所以可拆边}pp(x + 1, y);//不练的情况return;
}
void dfs2(ll x, ll y, ll z)
{if (x > k){memset(ss, 0, sizeof(ss));for (int i = 1; i <= k; ++i){if (!ss[s[i]]) ss[s[i]] = i;//找到相连的点中的第一个点,以这个点为父节点,ss和上面重复利用fa[i] = ss[s[i]];}fa[k + 1] = k + 1;pp(1, z);return;}for (int i = 1; i <= y; ++i)//再找一次有效状态{s[x] = i;dfs2(x + 1, y, z * 10 + i);s[x] = 0;}s[x] = y + 1;dfs2(x + 1, y + 1, z * 10 + y + 1);s[x] = 0;return;
}
void Counting(ll x)//快速幂
{while(x){if (x&1) A = A * B;B = B * B;x>>=1;}return;
}
int main()
{scanf("%lld%lld", &k, &n);dfs1(1, 0, 0);//得出编号dfs2(1, 0, 0);//连接状态A.n = 1;A.m = B.n = B.m = w;Counting(n - k);//初始状态已经是前k个printf("%lld", A.a[1][1]);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/320128.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[XSY] PQ树(区间DP)

PQ树 对于非叶子节点&#xff0c;它只能调换它的儿子的顺序&#xff0c;却不能调换整颗子树的顺序合法的PQ树都能表示出1,2,3,…,n 这个排列由以上两点可以得出&#xff1a;PQ树的每棵子树对应的一定都是一段连续的数字区间考虑区间DP&#xff0c;设f(l,r)f(l,r)f(l,r)表示数字…

牛客网 【每日一题】5月14日题目 maze

链接&#xff1a; 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 32768K&#xff0c;其他语言65536K 64bit IO Format: %lld题目描述 小明来到一个由n x m个格子组成的迷宫&#xff0c;有些格子是陷阱&#xff0c;用’#‘表示&#xff0c;小明…

你需要知道的这几种 asp.net core 修改默认端口的方式

一般情况下&#xff0c;aspnetcore发布后的默认端口是5000&#xff0c;这个大家都知道&#xff0c;而且默认骨架代码中没有看到任何让你输入的ip地址和端口号&#xff0c;但作为程序员的我们&#xff0c;不希望被框架所管制&#xff0c;那如何实现默认端口的修改呢&#xff1f;…

CF1139D-Steps to One【期望dp,莫比乌斯反演】

正题 题目链接:https://www.luogu.com.cn/problem/CF1139D 题目大意 不停的在表格中填下1∼m1\sim m1∼m中随机一个数&#xff0c;直到所有数的gcd1gcd1gcd1为止&#xff0c;求期望数的个数。 解题思路 设fnf_nfn​表示现在gcdgcdgcd为nnn时的期望个数。那么有转移方程fn∑i…

【DP】错排问题(ybtoj DP-1-1)

错排问题 ybtoj DP-1-1 题目大意 求n个数的错排种数 输入样例 2输出样例 1数据范围 1⩽n⩽201\leqslant n \leqslant 201⩽n⩽20 解题思路 设fif_ifi​为i个数的错排种数 考虑第i个数能放在前面i-1个位置的其中一个&#xff08;i-1种选法&#xff0c;要乘i-1&#xff0…

牛客网【每日一题】5月15日题目 储物点的距离

链接&#xff1a; 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 131072K&#xff0c;其他语言262144K 64bit IO Format: %lld题目描述 一个数轴&#xff0c;每一个储物点会有一些东西&#x…

[XSY] 最长公共子串对(后缀自动机)

最长公共子串对 先放一段考场暴力代码&#xff1a; #include<iostream> #include<cstdio> #include<cstring> using namespace std; char a[2005],b[2005]; int na,nb,f[2005][2005],c[2005][2005],ans; //f[i][j]表示 s[1...i]与 t[1...j]以s[i]、t[j]结尾…

P3911-最小公倍数之和【莫比乌斯反演】

正题 题目链接:https://www.luogu.com.cn/problem/P3911 题目大意 给出数列AAA求∑i1n∑j1nlcm(Ai,Aj)\sum_{i1}^n\sum_{j1}^nlcm(A_i,A_j)i1∑n​j1∑n​lcm(Ai​,Aj​) 解题思路 设cic_ici​表示AjiA_jiAj​i的个数&#xff0c;然后答案就是&#xff08;下面n5e4n5e4n5e4&…

【DP】奇怪汉诺塔(ybtoj DP-1-2)

奇怪汉诺塔 ybtoj DP-1-2 题目大意 求四根柱子的汉诺塔问题 输出 共12行 每行输出第一根柱子有i个圆盘的最小步数 解题思路 设aia_iai​表示三根柱子&#xff0c;第一根柱子有i个圆盘的步数 很显然是先移i-1个到第二根&#xff0c;再移最大的到第三根&#xff0c;再把i-…

牛客网【每日一题】5月18日 「土」秘法地震

链接&#xff1a; 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 帕秋莉掌握了一种土属性魔法 这种魔法可以在一片kk大小…

AspNetCore 中使用 InentityServer4(2)

基于上一篇文章 实现对IdnetityServer4 服务的使用1&#xff1a;添加接口解决方案&#xff0c;并且使接口受认证服务的保护&#xff1a;首先在解决方案中添加Api项目如下图所示&#xff1a;在API项目中添加Nuget 引用 如下图所示&#xff1a;Install-Package IdentityServer4.A…

[XSY] 宝藏(LCS,DP)

宝藏 首先&#xff0c;这个问题等价于给定两个字符串S,T &#xff0c;每次询问LCS(S[1,n],T[x,y])LCS(S[1,n],T[x,y])LCS(S[1,n],T[x,y])。 对每个询问重新求一遍LCSLCSLCS显然不现实&#xff0c;又因为yyy都是连续变化的&#xff0c;我们考虑探讨 LCS(S[1,n],T[x,y])与LCS(S[…

【DP】数的划分(ybtoj DP-1-3)

数的划分 ybtoj DP-1-1 题目大意 给你一个n&#xff0c;让你分成k份&#xff0c;问有多少种分法&#xff08;1,2和2,1为同一种&#xff09; 输入样例 7 3输出样例 4 样例解释 四种分法为&#xff1a;1,1,5;1,2,4;1,3,3;2,2,3.1,1,5; \ \ 1,2,4; \ \ 1,3,3; \ \ 2,2,3.1…

CF570D-Tree Requests【长链剖分】

正题 题目链接:https://www.luogu.com.cn/problem/CF570D 题目大意 nnn个点的一棵树&#xff0c;每个节点有字母&#xff0c;每次询问一个节点xxx的子树中深度为kkk的所有点的字母能否经过重排构成一个回文串。 解题思路 首先把每个字母的奇偶状压一下 然后方法比较多&#x…

牛客网 【每日一题】5月13日 加分二叉树

试题链接&#xff1a; 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 131072K&#xff0c;其他语言262144K 64bit IO Format: %lld题目描述 设一个n个节点的二叉树tree的中序遍历为&#xff0…

Visual Studio 2017 15.8概览

Microsoft正式发布VS2017的第八次更新&#xff0c;即15.8。15.8提供了今年夏天预览的大量新特性&#xff0c;包括Code Cleanup、IDE支持多重查补&#xff08;Multiple Caret&#xff09;、Visual Studio Code和ReSharper快捷键设置等。各类开发人员均可受益于这些已供使用的新特…

[XSY] 简单的数论题(数学、构造)

简单的数论题 m(a3b3)n(c3d3)m(a^3b^3)n(c^3d^3)m(a3b3)n(c3d3) 考虑因式分解(a3b3),(c3d3):考虑因式分解(a^3b^3),(c^3d^3):考虑因式分解(a3b3),(c3d3): a3b3(ab)3−3ab(ab)(ab)(a2b2−ab)a^3b^3(ab)^3-3ab(ab)(ab)(a^2b^2-ab)a3b3(ab)3−3ab(ab)(ab)(a2b2−ab) c3d3(cd)3−3c…

P4322-[JSOI2016]最佳团体【0/1分数规划,树形背包】

正题 题目链接:https://www.luogu.com.cn/problem/P4322 题目大意 nnn个点的一棵树&#xff0c;每个节点有一个(si,pi)(s_i,p_i)(si​,pi​)&#xff0c;选择一个点必须选择它的父节点&#xff0c;求选择KKK个点使得∑pxi∑sxi\frac{\sum p_{x_i}}{\sum s_{x_i}}∑sxi​​∑px…

【DP】平铺方案(ybtoj DP-1-5)

平铺方案 ybtoj DP-1-5 题目大意 求用121\times 212和222\times 222的瓦片平铺2n2\times n2n矩形的方案数 输入样例 2 8 12 100 200输出样例 3 171 2731 845100400152152934331135470251 1071292029505993517027974728227441735014801995855195223534251数据范围 0⩽n⩽2…

白兔的字符串

链接&#xff1a; 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 白兔有一个字符串T。白云有若干个字符串S1,S2…Sn。 白…