[BZOJ1494][NOI2007]生成树计数 状压dp 并查集
1494: [NOI2007]生成树计数
Time Limit: 5 Sec Memory Limit: 64 MB
Submit: 793 Solved: 451
[Submit][Status][Discuss]
Description
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< ...
随机推荐
- 算法(4) Rotate Image
题目:把一个N×N的矩阵旋转90° 思路:这个题目折腾了好长时间,确切地说是两个小时!这道题也反映出自己的逻辑比较混乱 这道题我到底卡在了哪里?自己已经在本子上画出了一个转移的关系 a[0][0] - ...
- maven第一个HelloWorld
1.Maven约定好的目录结构: maven01/src --main --java --package //包有多少级,加多少个子folder --新建一个HelloWorld.java --tes ...
- 【bzoj3653】谈笑风生 DFS序+树状数组
题目描述 给出一棵以1为根的有根树,q次询问,每次询问给出a和k,求点对 (b,c) 的数目,满足:a.b.c互不相同,b与a距离不超过k,且a和b都是c的祖先. 输入 输入文件的第一行含有两个正整数 ...
- LeetCode--Factorial Trailing Zeroes(注意)
Given an integer n, return the number of trailing zeroes in n!. 问题描述:给出一个正整数n,计算n!结构后面有几个0.要求:在多项式时间 ...
- Git 删除服务器的远程分支
git push origin :分支名 可能会出现,在A机子操作,刷新下成功删除,但在B机子上还显示,再用下命令提示不存在该分支,只要再推送一个任意分支即可正常显示
- vim插件修改背景颜色和代码颜色
ls /usr/share/vim/vim74/colorsblue.vim default.vim desert.vim evening.vim morning.vim pablo.vim READ ...
- codeforces 1065D
题目链接:https://codeforces.com/problemset/problem/1065/D 题意:给你一个又1~n^2组成的n行n列的矩阵,你可以走日字型,直线,斜线,现在要求你从1走 ...
- angularjs的验证信息的写法
<div ng-messages="alarmDelayForm.alarmRuleName.$error" role="alert"> <d ...
- webstorm中把style的内容隐藏,如何把style的内容展开?
我们经常看到在webstorm中style的内容以...表示如下图所示,只有把光标移到上面时才会看到内容: 如何把上述的style的内容展开呢? 请按一下步骤操作: 第一步:File------> ...
- css的padding,border,margin的意思
下面的内边距(padding).边框(border) .外边距(margin)的意思是我自己的理解. 代码如下: <!DOCTYPE html> <html lang="e ...