[luogu7418]Counting Graphs P
参考[luogu7417],同样求出最短路,得到二元组$(x,y)$并排序,记$tot_{(x,y)}$为$(x,y)$的数量
其中所给的两个条件,即分别要求:
1.$(x,y)$只能和$(x\pm 1,y\pm 1)$连边
2.每一个$(x,y)$都向$(x-1,y\pm 1)$中的一个连边、$(x\pm 1,y-1)$中的一个连边
(另外,注意在$x+1=y$时$(x+1,y-1)$也即为$(x,y)$自身)
从前往后依次dp,假设考虑到二元组为$(x,y)$,将之前二元组分为两类——
(1)对于其中不为$(x,y)$的二元组之后已经不存在能通过连边满足第2个条件的点了,那么就需要保证第2个条件都已经满足,即状态中不需要再记录
(2)对于二元组$(x,y)$,之后也不存在$(x-1,y\pm 1)$的点了,因此$x$的一维必须要已经满足,并记录$y$的一维不满足的数个数即可
由此,即得到一个二维的状态,将其记为$f_{(x,y),i}$(其中$i$的定义参考(2)中)
关于转移,有以下四类本质不同的边:
(1)$(x,y)$与$(x-1,y+1)$中$y$的一维已经满足点的的边
(2)$(x,y)$与$(x-1,y+1)$中$y$的一维仍未满足的点的边
(3)$(x,y)$与$(x-1,y-1)$的边
(4)若$x+1=y$,$(x,y)$和$(x,y)$之间的边
先转移前两类边(避免出现三维状态),枚举后者的点数,转移即
$$
f_{(x,y),i}={tot_{(x,y)}\choose i}\sum_{j=0}^{tot_{(x-1,y+1)}}G(tot_{(x-1,y+1)},j,tot_{(x,y)}-i)f_{(x-1,y+1),j}
$$
(注意此时的$i$的定义并不为最终的定义,仅是一个中间过程)
其中$G(x,z,y)$表示在左边$x$个点和右边$y$个点连边的$2^{xy}$张图中,满足左边特定的$z$个点(如前$z$个点)和右边的$y$个点度数均非0的方案数,对左边容斥有
$$
G(x,z,y)=\sum_{i=0}^{z}(-1)^{i}{z\choose i}(2^{x-i}-1)^{y}
$$
再转移第3类边,考虑转移的状态$f_{(x,y),j}$,这$j$个点必须都选择(否则$x$这一维不满足),因此转移即
$$
f_{(x,y),i}=\sum_{j=0}^{tot_{(x,y)}}{tot_{(x,y)}-j\choose i}(2^{tot_{(x-1,y-1)}}-1)^{tot_{(x,y)}-i}f_{(x,y),j}
$$
(这里是类似于01背包的,即后者$f_{(x,y),j}$应该是未转移第3类边的结果)
最后转移第4类边,其实这只是一个特例,更完整的情况应该是对于$(x+1,y-1)$不再出现的点(即其之后不再参与转移,之后也没有点可以帮助其满足第2个条件)将其的贡献乘到答案上
具体的,这类状态又分为两类:
1.$x+1\ne y$,这类状态不能通过自环使其满足条件,因此贡献即$f_{(x,y),0}$
2.$x+1=y$,这还可以通过自环使其满足条件
具体的,贡献即$\sum_{i=0}^{tot_{(x,y)}}G(tot_{(x,y)},i)f_{(x,y),i}$,其中$G(x,y)$表示在$x$个点中任意连边的$2^{\frac{x(x+1)}{2}}$张图中(允许自环),满足特定的$y$个点度数均非0的方案数,对这$y$个点容斥有
$$
G(x,y)=\sum_{i=0}^{y}(-1)^{i}{y\choose i}2^{\frac{(x-i)(x-i+1)}{2}}
$$
不难发现$f$的状态数实际仅为$o(n)$,转移复杂度为$o(n^{2})$,总复杂度即$o(n^{3})$,可以通过
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 105
4 #define M 10005
5 #define mod 1000000007
6 #define oo 0x3f3f3f3f
7 #define ll long long
8 struct Edge{
9 int nex,to;
10 }edge[M*3];
11 queue<int>q;
12 int t,n,m,E,x,y,ans,mi[M],Mi[N][N],C[N][N],head[N<<1],d[N<<1],tot[N][N],g[N],f[N];
13 void add(int x,int y){
14 edge[E].nex=head[x];
15 edge[E].to=y;
16 head[x]=E++;
17 }
18 int G(int x,int y){
19 int ans=0;
20 for(int i=0;i<=y;i++){
21 int s=(ll)C[y][i]*mi[(x-i)*(x-i+1)/2]%mod;
22 if (i&1)ans=(ans-s+mod)%mod;
23 else ans=(ans+s)%mod;
24 }
25 return ans;
26 }
27 int G(int x,int z,int y){
28 int ans=0;
29 for(int i=0;i<=z;i++){
30 int s=(ll)C[z][i]*Mi[x-i][y]%mod;
31 if (i&1)ans=(ans-s+mod)%mod;
32 else ans=(ans+s)%mod;
33 }
34 return ans;
35 }
36 int main(){
37 mi[0]=1;
38 for(int i=1;i<M;i++)mi[i]=2*mi[i-1]%mod;
39 for(int i=0;i<N;i++){
40 Mi[i][0]=1;
41 for(int j=1;j<N;j++)Mi[i][j]=(ll)Mi[i][j-1]*(mi[i]-1)%mod;
42 }
43 for(int i=0;i<N;i++){
44 C[i][0]=C[i][i]=1;
45 for(int j=1;j<i;j++)C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
46 }
47 scanf("%d",&t);
48 while (t--){
49 scanf("%d%d",&n,&m);
50 E=0,ans=1;
51 memset(head,-1,sizeof(head));
52 memset(d,oo,sizeof(d));
53 memset(tot,0,sizeof(tot));
54 for(int i=1;i<=m;i++){
55 scanf("%d%d",&x,&y);
56 add(x,y+n),add(y+n,x);
57 add(x+n,y),add(y,x+n);
58 }
59 d[1]=0;
60 q.push(1);
61 while (!q.empty()){
62 int k=q.front();
63 q.pop();
64 for(int i=head[k];i!=-1;i=edge[i].nex)
65 if (d[edge[i].to]==oo){
66 d[edge[i].to]=d[k]+1;
67 q.push(edge[i].to);
68 }
69 }
70 if (d[n+1]==oo){
71 for(int i=1;i<=n;i++)tot[0][min(d[i],d[i+n])]++;
72 for(int i=1;i<=n;i++)ans=(ll)ans*Mi[tot[0][i-1]][tot[0][i]]%mod;
73 printf("%d\n",ans);
74 continue;
75 }
76 for(int i=1;i<=n;i++)tot[d[i]+d[i+n]-d[n+1]>>1][min(d[i],d[i+n])]++;
77 for(int x=0;x<=n;x++){
78 memset(f,0,sizeof(f));
79 f[0]=1;
80 for(int y=x;y<=n;y++){
81 if (!tot[x][y]){
82 if (y-x<=(d[n+1]>>1))ans=(ll)ans*f[0]%mod;
83 else{
84 int s=0;
85 for(int i=0;i<=tot[x][y-1];i++)s=(s+(ll)G(tot[x][y-1],i)*f[i])%mod;
86 ans=(ll)ans*s%mod;
87 }
88 memset(f,0,sizeof(f));
89 f[0]=1;
90 continue;
91 }
92 if ((!x)&&(!y)){
93 f[0]=0,f[1]=1;
94 continue;
95 }
96 memcpy(g,f,sizeof(g));
97 memset(f,0,sizeof(f));
98 for(int i=0;i<=tot[x][y];i++){
99 int s=0;
100 for(int j=0;j<=tot[x][y-1];j++)s=(s+(ll)G(tot[x][y-1],j,tot[x][y]-i)*g[j])%mod;
101 f[i]=(f[i]+(ll)C[tot[x][y]][i]*s)%mod;
102 }
103 memcpy(g,f,sizeof(g));
104 memset(f,0,sizeof(f));
105 if (!x){
106 f[tot[x][y]]=g[0];
107 continue;
108 }
109 for(int i=0;i<=tot[x][y];i++)
110 for(int j=0;j<=tot[x][y];j++)f[i]=(f[i]+(ll)C[tot[x][y]-j][i]*Mi[tot[x-1][y-1]][tot[x][y]-i]%mod*g[j])%mod;
111 }
112 }
113 printf("%d\n",ans);
114 }
115 return 0;
116 }
[luogu7418]Counting Graphs P的更多相关文章
- Python Object Graphs — objgraph 1.7.2 documentation
Python Object Graphs - objgraph 1.7.2 documentation Python Object Graphs¶ objgraph is a module that ...
- ARC(Automatic Reference Counting )技术概述
此文章由Tom翻译,首发于csdn的blog 转自:http://blog.csdn.net/nicktang/article/details/6792972 Automatic Reference ...
- 萌新笔记——Cardinality Estimation算法学习(二)(Linear Counting算法、最大似然估计(MLE))
在上篇,我了解了基数的基本概念,现在进入Linear Counting算法的学习. 理解颇浅,还请大神指点! http://blog.codinglabs.org/articles/algorithm ...
- POJ_2386 Lake Counting (dfs 错了一个负号找了一上午)
来之不易的2017第一发ac http://poj.org/problem?id=2386 Lake Counting Time Limit: 1000MS Memory Limit: 65536 ...
- ZOJ3944 People Counting ZOJ3939 The Lucky Week (模拟)
ZOJ3944 People Counting ZOJ3939 The Lucky Week 1.PeopleConting 题意:照片上有很多个人,用矩阵里的字符表示.一个人如下: .O. /|\ ...
- find out the neighbouring max D_value by counting sort in stack
#include <stdio.h> #include <malloc.h> #define MAX_STACK 10 ; // define the node of stac ...
- 1004. Counting Leaves (30)
1004. Counting Leaves (30) A family hierarchy is usually presented by a pedigree tree. Your job is ...
- 6.Counting Point Mutations
Problem Figure 2. The Hamming distance between these two strings is 7. Mismatched symbols are colore ...
- 1.Counting DNA Nucleotides
Problem A string is simply an ordered collection of symbols selected from some alphabet and formed i ...
随机推荐
- MySQL技术专题(X)该换换你的数据库版本了,让我们一同迎接8.0的到来哦!(初探篇)
前提背景 MySQL关是一种关系数据库管理系统,所使用的 SQL 语言是用于访问数据库的最常用的标准化语言,其特点为体积小.速度快.总体拥有成本低,尤其是开放源码这一特点,在 Web应用方面 MySQ ...
- C#开发BIMFACE系列43 服务端API之图纸拆分
BIMFACE二次开发系列目录 [已更新最新开发文章,点击查看详细] 在上一篇博客<C#开发BIMFACE系列42 服务端API之图纸对比>的最后留了一个问题,在常规业务场景下,一 ...
- 【集成学习】:Stacking原理以及Python代码实现
Stacking集成学习在各类机器学习竞赛当中得到了广泛的应用,尤其是在结构化的机器学习竞赛当中表现非常好.今天我们就来介绍下stacking这个在机器学习模型融合当中的大杀器的原理.并在博文的后面附 ...
- ❤️这应该是Postman最详细的中文使用教程了❤️(新手使用,简单明了)
️这应该是Postman最详细的中文使用教程了️(新手使用,简单明了) 在前后端分离开发时,后端工作人员完成系统接口开发后,需要与前端人员对接,测试调试接口,验证接口的正确性可用性.而这要求前端开发进 ...
- C#开发BIMFACE系列53 WinForm程序中使用CefSharp加载模型图纸1 简单应用
BIMFACE二次开发系列目录 [已更新最新开发文章,点击查看详细] 在我的博客<C#开发BIMFACE系列52 CS客户端集成BIMFACE应用的技术方案>中介绍了多种集成BIM ...
- Bug概述、状态、类型、级别、优先级提交和Bug生命周期管理
缺陷概述: 1)缺陷(Defect):是指存在于软件之中偏差,可被激活,以静态形式存在于软件内部,相当于Bug. 2)故障(Fault):当缺陷被激活后,软件运⾏中出现的状态,可引起意外情况,若不加处 ...
- HttpRunner3.X - 实现参数化驱动
一.前言 HttpRunner3.X支持三种方式的参数化,参数名称的定义分为两种情况: 独立参数单独进行定义: 多个参数具有关联性的参数需要将其定义在一起,采用短横线(-)进行连接. 数据源指定支持三 ...
- JavaScript中的函数、参数、变量
高中大学数学很差,学JavaScript,发现根本不理解其中的函数.参数.变量等概念. 李永乐老师教学视频:<高三数学复习100讲>函数 bilibili.com/video/av5087 ...
- python的虚拟环境Anaconda使用
Anaconda 使用conda常用命令 1.首先在所在系统中安装Anaconda.可以打开命令行输入conda -V检验是否安装以及当前conda的版本. 2.conda常用的命令. 1)con ...
- 5.31日 Scrum Metting
日期:2021年5月31日 会议主要内容概述:讨论草稿箱前后端接口,讨论账单页面设计. 一.进度情况 组员 负责 两日内已完成的工作 后两日计划完成的工作 工作中遇到的困难 徐宇龙 后端 文件导入功能 ...