参考[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的更多相关文章

  1. Python Object Graphs — objgraph 1.7.2 documentation

    Python Object Graphs - objgraph 1.7.2 documentation Python Object Graphs¶ objgraph is a module that ...

  2. ARC(Automatic Reference Counting )技术概述

    此文章由Tom翻译,首发于csdn的blog 转自:http://blog.csdn.net/nicktang/article/details/6792972 Automatic Reference ...

  3. 萌新笔记——Cardinality Estimation算法学习(二)(Linear Counting算法、最大似然估计(MLE))

    在上篇,我了解了基数的基本概念,现在进入Linear Counting算法的学习. 理解颇浅,还请大神指点! http://blog.codinglabs.org/articles/algorithm ...

  4. POJ_2386 Lake Counting (dfs 错了一个负号找了一上午)

    来之不易的2017第一发ac http://poj.org/problem?id=2386 Lake Counting Time Limit: 1000MS   Memory Limit: 65536 ...

  5. ZOJ3944 People Counting ZOJ3939 The Lucky Week (模拟)

    ZOJ3944 People Counting ZOJ3939 The Lucky Week 1.PeopleConting 题意:照片上有很多个人,用矩阵里的字符表示.一个人如下: .O. /|\ ...

  6. 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 ...

  7. 1004. Counting Leaves (30)

    1004. Counting Leaves (30)   A family hierarchy is usually presented by a pedigree tree. Your job is ...

  8. 6.Counting Point Mutations

    Problem Figure 2. The Hamming distance between these two strings is 7. Mismatched symbols are colore ...

  9. 1.Counting DNA Nucleotides

    Problem A string is simply an ordered collection of symbols selected from some alphabet and formed i ...

随机推荐

  1. uoj22 外星人(dp)

    题目大意: 给定一个\(n\)个数的序列\(a\),给定一个\(x\),其中\(a\)数组可以进行顺序的调换,每一个\(a_i\)都能使$x=x \mod a_i \(, 求最后经过一系列计算后的\) ...

  2. Spark RDD编程(博客索引,日常更新)

    本篇主要是记录自己在中解决RDD编程性能问题中查阅的论文博客,为我认为写的不错的建立索引方便查阅,我的总结会另立他篇 1)通过分区(Partitioning)提高spark性能https://blog ...

  3. javascript-jquery对象的css处理

    一.css基本属性处理 1.css()方法:获取css属性值.$("选择器").css(name);//获取匹配选择器的元素指定css属性值. 2.css()方法:设置css属性值 ...

  4. (半课内)信安数基 RSA-OAEP 初探

    在RSA攻击中,存在着"小明文攻击"的方式: 在明文够小时,密文也够小,直接开e次方即可: 在明文有点小时,如果e也较小,可用pow(m,e)=n*k+c穷举k尝试爆破 所以,比如 ...

  5. JavaScript之原型与原型链

    前言 ❝ JavaScript常被描述为一种「基于原型的语言」--每个对象都拥有一个「原型对象」,对象以其原型为模板.从原型继承属性和放法.原型对象也可能拥有原型,并从中继承属性和方法,一层一层以此类 ...

  6. 【UE4 C++】简单获取名称、状态、时间、帧数、路径与FPaths

    基于UKismetSystemLibrary 获取各类名称 // Returns the actual object name. UFUNCTION(BlueprintPure, Category = ...

  7. 【数据结构与算法Python版学习笔记】图——强连通分支

    互联网 我们关注一下互联网相关的非常巨大图: 由主机通过网线(或无线)连接而形成的图: 以及由网页通过超链接连接而形成的图. 网页形成的图 以网页(URI作为id)为顶点,网页内包含的超链接作为边,可 ...

  8. Java:关于 CAS 笔记

    Java:关于 CAS 笔记 本笔记是根据bilibili上 尚硅谷 的课程 Java大厂面试题第二季 而做的笔记 1. CAS 底层原理 概念 CAS 的全称是 Compare-And-Swap,它 ...

  9. UltraSoft - Alpha - Scrum Meeting 7

    Date: Apr 22th, 2020. Scrum 情况汇报 进度情况 组员 负责 昨日进度 后两日任务 CookieLau PM 完成课程中心的json格式传递 完成邮箱验证机制 刘zh 前端 ...

  10. 人人都写过的5个Bug!

    大家好,我是良许. 计算机专业的小伙伴,在学校期间一定学过 C 语言.它是众多高级语言的鼻祖,深入学习这门语言会对计算机原理.操作系统.内存管理等等底层相关的知识会有更深入的了解,所以我在直播的时候, ...