[BZOJ1494][NOI2007]生成树计数 状压dp 并查集
1494: [NOI2007]生成树计数
Time Limit: 5 Sec Memory Limit: 64 MB
Submit: 793 Solved: 451
[Submit][Status][Discuss]
Description
.png)

.png)
.png)
.png)

.png)
.png)
Input
包含两个整数k,n,由一个空格分隔。k表示要将所有距离不超过k(含k)的结点连接起来,n表示有n个结点。
Output
输出一个整数,表示生成树的个数。由于答案可能比较大,所以你 只要输出答案除65521 的余数即可。
Sample Input
Sample Output
HINT

Source
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define maxn 150
#define mod 65521
using namespace std;
int size[]={,,,,,};
long long n,k;int cnt;
struct data {
long long mat[maxn+][maxn+];
data() {memset(mat,,sizeof(mat));}
data operator *(const data t1) {
data tp;
for(int i=;i<=cnt;i++)
for(int j=;j<=cnt;j++)
for(int k=;k<=cnt;k++) tp.mat[i][j]+=mat[i][k]*t1.mat[k][j],tp.mat[i][j]%=mod;
return tp;
}
}A,B;
int hash[],sta[];
int fa[];
int find(int x){return fa[x]==x?fa[x]:fa[x]=find(fa[x]);}
void prepare(int pos,int now,int ma) {
if(pos==k+) {
hash[now]=cnt++;
sta[cnt-]=now;
return;
}
for(int i=;i<=ma;i++) prepare(pos+,now+(i<<(*(pos-))),ma+(i==ma));
}
int get() {
int h[];
memset(h,-,sizeof(h));
int re=;
int cc=;
for(int i=;i<=k+;i++) {
if(h[find(i)]==-) h[find(i)]=++cc;
}
for(int i=;i<=k+;i++) {
int now=h[find(i)];
re+=(now<<(*(i-)));
}
return hash[re];
}
void build(int x,int add) {
int now=sta[x];
for(int i=;i<=k+;i++) fa[i]=i;
for(int i=;i<=k;i++) {
for(int j=i+;j<=k;j++) {
if(((now>>((i-)*))&)==((now>>((j-)*))&)) {
int f1=find(i),f2=find(j);
if(f1!=f2) fa[f1]=f2;
}
}
}
for(int i=;i<=k;i++) {
if(add&(<<(i-))) {
int f1=find(i),f2=find(k+);
if(f1==f2) return;
fa[f1]=f2;
}
}
bool flag=;
for(int i=;i<=k+;i++) {
if(find()==find(i)) {flag=;break;}
}
if(!flag) return;
A.mat[get()][x]++;
}
data pow(data x,long long p) {
data ans;
for(int i=;i<=maxn;i++) ans.mat[i][i]=;
while(p) {
if(p&) ans=ans*x;
x=x*x;
p>>=; }
return ans;
}
int main() {
for(int i=;i<=maxn;i++) B.mat[i][]=;
scanf("%lld%lld",&k,&n);
prepare(,,);
for(int i=;i<cnt;i++)
for(int j=;j<(<<k);j++) build(i,j);
/*for(int i=0;i<cnt;i++) {
for(int j=0;j<=k;j++) cout<<A.mat[i][j]<<' ';
cout<<endl;
}*/
for(int i=;i<cnt;i++) {
int now=sta[i];
int tmp[]={};
for(int j=;j<=k;j++) tmp[now>>((j-)*)&]++;
for(int j=;j<=k;j++) B.mat[i][]*=size[tmp[j]];
} A=pow(A,n-k);
A=A*B;
printf("%lld",A.mat[][]%mod);
}
[BZOJ1494][NOI2007]生成树计数 状压dp 并查集的更多相关文章
- HDU5117 Fluorescent 期望 计数 状压dp 动态规划
原文链接https://www.cnblogs.com/zhouzhendong/p/HDU5117.html 题目传送门 - HDU5117 题意 $T$ 组数据. 给你 $n$ 盏灯 ,$m$ 个 ...
- BZOJ1494 [NOI2007]生成树计数
题意 F.A.Qs Home Discuss ProblemSet Status Ranklist Contest 入门OJ ModifyUser autoint Logout 捐赠本站 Probl ...
- CCPC-Wannafly Winter Camp Day3 Div1 - 精简改良 - [生成树][状压DP]
题目链接:https://zhixincode.com/contest/14/problem/D?problem_id=206 样例输入 1 5 5 1 2 1 1 3 1 2 4 1 2 5 1 ...
- hdu5304 Eastest Magical Day Seep Group's Summer 状压dp+生成树
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5304 16个点的无向图,问能生成多少个n条边的连通图.(即多一条边的树) 先n^3 * 2^n 枚举全部的 ...
- 状态压缩动态规划 状压DP
总述 状态压缩动态规划,就是我们俗称的状压DP,是利用计算机二进制的性质来描述状态的一种DP方式 很多棋盘问题都运用到了状压,同时,状压也很经常和BFS及DP连用,例题里会给出介绍 有了状态,DP就比 ...
- AGC 016 F - Games on DAG(状压dp)
题意 给你一个有 \(n\) 个点 \(m\) 条边 DAG 图,点的标号和拓扑序一致. 现在有两个人进行博弈,有两个棋子分别在 \(1, 2\) 号点上,需要不断移动到它指向的点上. 如果当前两个点 ...
- P1879 [USACO06NOV]玉米田Corn Fields 状压dp/插头dp
正解:状压dp/插头dp 解题报告: 链接! ……我真的太菜了……我以为一个小时前要搞完的题目调错误调了一个小时……90分到100我差不多搞了一个小时…… 然后这题还是做过的……就很气,觉得确实是要搞 ...
- BZOJ.3058.四叶草魔杖(Kruskal 状压DP)
题目链接 \(2^{16}=65536\),可以想到状压DP.但是又有\(\sum A_i\neq 0\)的问题.. 但是\(2^n\)这么小,完全可以枚举所有子集找到\(\sum A_i=0\)的, ...
- 【ZJOI2017 Round1练习&BZOJ4774】D3T2 road(斯坦纳树,状压DP)
题意: 对于边带权的无向图 G = (V, E),请选择一些边, 使得1<=i<=d,i号节点和 n − i + 1 号节点可以通过选中的边连通, 最小化选中的所有边的权值和. d< ...
随机推荐
- maven第一个HelloWorld
1.Maven约定好的目录结构: maven01/src --main --java --package //包有多少级,加多少个子folder --新建一个HelloWorld.java --tes ...
- JS调用C#中的变量
今天早上做项目,需要使用JS来得到数据库里面表的行数.经过查找资料,知道可以使用在C#中定义一个全局变量.在JS中调用即可,自己总结一下:供日后参考; public string Str() { st ...
- sql如何先排序再去重
场景 有一张得分表(score),记录了用户每次的得分,同一个人可能有多个得分. id name score 1 tom 45 2 jack 78 3 tom 34 . . . 需求:找出分数最高的前 ...
- IE提示是否只查看安全传送的网页内容
IE选项-->安全-->点上面那个地球internet-->点下面那个 自定义级别-->找到“其他”-->显示混合内容,改为启用,重启打开下IE,就可以了
- [洛谷P4779]【模板】单源最短路径(标准版)
题目大意:单元最短路径(卡$SPFA$) 题解:$dijkstra$($\underline{\hspace{0.5em}}\underline{\hspace{0.5em}}gnu\underlin ...
- 【BZOJ 3144】 [Hnoi2013]切糕 真·最小割
一开始一脸懵逼后来发现,他不就是割吗,我们只要满足条件就割就行了,于是我们把他连了P*Q*R条边,然而我们要怎样限制D呢?我们只要满足对于任意相邻的两条路,只要其有个口大于D就不行就好了因此我们只要把 ...
- [bzoj1033] [ZJOI2008]杀蚂蚁 Big MoNI
这个模拟就不用说了吧...... 注意事项(救命的):1.不能回原位 2.在可以打到target的塔打target的时候,其他打不到的继续打自己的(这是显然的事情只是当时已惘然) 3.如果游戏在某一秒 ...
- bzoj3343: 教主的魔法 分块 标记
修改:两边暴力重构,中间打标记.复杂度:O(n0.5) 查询:中间二分两边暴力.O(n0.5logn0.5) 总时间复杂度O(n*n0.5logn0.5) 空间复杂度是n级别的 标记不用下传因为标记不 ...
- [cdoj 1344]树状数组区间加等差数列
题目链接:http://acm.uestc.edu.cn/#/problem/show/1344 区间加等差数列本质上就是区间修改区间查询,本来想用线段树做,结果这个题就是卡空间和时间……不得已学了区 ...
- codeforces902C. Hashing Trees
https://codeforces.com/contest/902/problem/C 题意: 给你树的深度和树的每个节点的深度,问你是否有重构,如果有重构输出两个不同的结构 题解: 如果相邻节点的 ...