其实这三道题都是不错的……(虽然感觉第三题略套路了……)

分别写一下做法好了……

COGS2392 有标号的二分图计数 I

这个就很简单了,Noip难度。

显然可以直接认为黑点和白点分别位于二分图两侧,枚举二分图左侧的点数,如果左侧的点数为$k$,那么就有$C_n^k$种选择方案,并且有$k(n-k)$条边可选,因为每条边都可以选或不选,因此答案就是

\begin{align}\sum_{k=0}^n C_n^k 2^{k(n-k)}\end{align}

由于只需求出一个答案,直接快速幂搞一搞即可,复杂度$O(n\log n)$。

 #include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
#define fac(x) (((x)<(0))?(0):(f[(x)]))
using namespace std;
const int maxn=;
const LL p=998244353ll;
LL inv(LL);
LL qpow(LL,LL);
LL C(int,int);
int n;
LL f[maxn<<],ans=;
int main(){
#define MINE
#ifdef MINE
freopen("QAQ_bipartite_one.in","r",stdin);
freopen("QAQ_bipartite_one.out","w",stdout);
#endif
scanf("%d",&n);
f[]=1ll;
for(int i=;i<=n;i++)f[i]=f[i-]*i%p;
for(int i=;i<=n;i++)(ans+=C(n,i)*qpow(2ll,(LL)(n-i)*i%(p-1ll)))%=p;
printf("%d",(int)ans);
return ;
}
LL inv(LL x){
return qpow(x,p-2ll);
}
LL qpow(LL a,LL b){
LL ans=1ll;
for(;b;b>>=,(a*=a)%=p)if(b&1ll)(ans*=a)%=p;
return ans;
}
LL C(int n,int m){
return fac(n)*inv(fac(m)*fac(n-m)%p)%p;
}

(这代码是我很久之前写的了,十分丑陋,不要介意……)

COGS2393 有标号的二分图计数 II

设上一题的指数生成函数是$F(x)$,这题的指数生成函数为$G(x)$,强制必须连通的指数生成函数是$H(x)$,显然有

\begin{align}G=\sum_{i=0}^\infty\frac{H^i}{i!}=e^{H}\end{align}

然后考虑$F$和$H$的关系,如果某个二分图有$k$个连通块,那么它在第一题中就会被计算$2^k$次,所以我们需要把每一项乘上$2^k$,因此就有

\begin{align}F=\sum_{i=0}^\infty\frac{2^iH^i}{i!}=e^{2H}\end{align}

然后可以看出来$F=G^2$,也就是$G=\sqrt F$,跑一下多项式开根即可求出$G$。

但是还有一个最重要的问题,这个$F$不好算……

$F$显然是没法直接算了,但观察到$F$的形式和卷积比较像,因此我们可以尝试把$F$化成卷积形式。显然最碍事的就是$2^{n(n-k)}$了,只要解决掉它,一切就都好说了。

首先我们有$k(n-k)=k^2-nk$,把$nk$用$\frac{n^2+k^2-(n-k)^2}2$替换之后就可以得到$k(n-k)=\frac{n^2-k^2-(n-k)^2}2$,因此$2^{k(n-k)}=\frac{\left(\sqrt 2\right)^{n^2}}{\left(\sqrt 2\right)^{k^2}\left(\sqrt 2\right)^{(n-k)^2}}$,然后就是卷积形式了,一遍NTT即可求出$F$。

ps:我没有想出来,这是看了ad学长的题解才明白的,感觉还是比较妙啊……

在$\mod 998244353$意义下是存在$\sqrt 2$的,暴力一下并把暴力出的答案直接写到代码里即可。

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=,p=,g=,sqrt_2=,inv_2=;
void NTT(int*,int,int);
void getsqrt(int*,int*,int);
void getinv(int*,int*,int);
int qpow(int,int,int);
int n,N=,A[maxn],B[maxn],fac[maxn],pw[maxn];
int main(){
freopen("QAQ_bipartite_two.in","r",stdin);
freopen("QAQ_bipartite_two.out","w",stdout);
scanf("%d",&n);
while(N<=n)N<<=;
A[]=fac[]=pw[]=;
for(int i=;i<=n;i++){
fac[i]=(long long)fac[i-]*i%p;
pw[i]=qpow(sqrt_2,(long long)i*i%(p-),p);
A[i]=qpow((long long)fac[i]*pw[i]%p,p-,p);
}
NTT(A,N<<,);
for(int i=;i<(N<<);i++)A[i]=(long long)A[i]*A[i]%p;
NTT(A,N<<,-);
for(int i=;i<=n;i++)A[i]=(long long)A[i]*pw[i]%p;
fill(A+n+,A+(N<<),);
getsqrt(A,B,N);
printf("%d",(int)((long long)B[n]*fac[n]%p));
return ;
}
void NTT(int *A,int n,int tp){
for(int i=,j=,k;i<n-;i++){
k=n;
do j^=(k>>=);while(j<k);
if(i<j)swap(A[i],A[j]);
}
for(int k=;k<=n;k<<=){
int wn=qpow(g,(tp>?(p-)/k:(p-)/k*(long long)(p-)%(p-)),p);
for(int i=;i<n;i+=k){
int w=;
for(int j=;j<(k>>);j++,w=(long long)w*wn%p){
int a=A[i+j],b=(long long)w*A[i+j+(k>>)]%p;
A[i+j]=(a+b)%p;
A[i+j+(k>>)]=(a-b+p)%p;
}
}
}
if(tp<){
int inv=qpow(n,p-,p);
for(int i=;i<n;i++)A[i]=(long long)A[i]*inv%p;
}
}
void getsqrt(int *A,int *C,int n){
static int B[maxn],D[maxn];
fill(C,C+(n<<),);
C[]=;
for(int k=;k<=n;k<<=){
copy(A,A+k,B);
fill(B+k,B+(k<<),);
getinv(C,D,k);
NTT(B,k<<,);
NTT(D,k<<,);
for(int i=;i<(k<<);i++)B[i]=(long long)B[i]*D[i]%p;
NTT(B,k<<,-);
for(int i=;i<k;i++)C[i]=(long long)(C[i]+B[i])*inv_2%p;
}
}
void getinv(int *A,int *C,int n){
static int B[maxn];
fill(C,C+(n<<),);
C[]=qpow(A[],p-,p);
for(int k=;k<=n;k<<=){
copy(A,A+k,B);
fill(B+k,B+(k<<),);
NTT(B,k<<,);
NTT(C,k<<,);
for(int i=;i<(k<<);i++)C[i]=C[i]*((-(long long)B[i]*C[i]%p+p)%p)%p;
NTT(C,k<<,-);
fill(C+k,C+(k<<),);
}
}
int qpow(int a,int b,int p){
int ans=;
for(;b;b>>=,a=(long long)a*a%p)if(b&)ans=(long long)ans*a%p;
return ans;
}

COGS2395 有标号的二分图计数 III

你还记得$F=e^{2H}$不……

然后就很好说了,多项式$\ln$之后答案就是对应项系数$/2$……

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=,p=,g=,sqrt_2=,inv_2=;
void NTT(int*,int,int);
void getln(int*,int*,int);
void getinv(int*,int*,int);
void getderivative(int*,int*,int);
void getintegrate(int*,int*,int);
int qpow(int,int,int);
int n,N=,A[maxn],B[maxn],fac[maxn],pw[maxn];
int main(){
freopen("QAQ_bipartite_thr.in","r",stdin);
freopen("QAQ_bipartite_thr.out","w",stdout);
scanf("%d",&n);
while(N<=n)N<<=;
A[]=fac[]=pw[]=;
for(int i=;i<=n;i++){
fac[i]=(long long)fac[i-]*i%p;
pw[i]=qpow(sqrt_2,(long long)i*i%(p-),p);
A[i]=qpow((long long)fac[i]*pw[i]%p,p-,p);
}
NTT(A,N<<,);
for(int i=;i<(N<<);i++)A[i]=(long long)A[i]*A[i]%p;
NTT(A,N<<,-);
for(int i=;i<=n;i++)A[i]=(long long)A[i]*pw[i]%p;
fill(A+n+,A+(N<<),);
getln(A,B,N);
printf("%d",(int)((long long)B[n]*fac[n]%p*inv_2%p));
return ;
}
void NTT(int *A,int n,int tp){
for(int i=,j=,k;i<n-;i++){
k=n;
do j^=(k>>=);while(j<k);
if(i<j)swap(A[i],A[j]);
}
for(int k=;k<=n;k<<=){
int wn=qpow(g,(tp>?(p-)/k:(p-)/k*(long long)(p-)%(p-)),p);
for(int i=;i<n;i+=k){
int w=;
for(int j=;j<(k>>);j++,w=(long long)w*wn%p){
int a=A[i+j],b=(long long)w*A[i+j+(k>>)]%p;
A[i+j]=(a+b)%p;
A[i+j+(k>>)]=(a-b+p)%p;
}
}
}
if(tp<){
int inv=qpow(n,p-,p);
for(int i=;i<n;i++)A[i]=(long long)A[i]*inv%p;
}
}
void getln(int *A,int *C,int n){
static int B[maxn];
getderivative(A,B,n);
getinv(A,C,n);
NTT(B,n<<,);
NTT(C,n<<,);
for(int i=;i<(n<<);i++)B[i]=(long long)B[i]*C[i]%p;
NTT(B,n<<,-);
getintegrate(B,C,n);
fill(C+n,C+(n<<),);
}
void getinv(int *A,int *C,int n){
static int B[maxn];
fill(C,C+(n<<),);
C[]=qpow(A[],p-,p);
for(int k=;k<=n;k<<=){
copy(A,A+k,B);
fill(B+k,B+(k<<),);
NTT(B,k<<,);
NTT(C,k<<,);
for(int i=;i<(k<<);i++)C[i]=C[i]*((-(long long)B[i]*C[i]%p+p)%p)%p;
NTT(C,k<<,-);
fill(C+k,C+(k<<),);
}
}
void getderivative(int *A,int *C,int n){
for(int i=;i<n;i++)C[i-]=(long long)A[i]*i%p;
C[n-]=;
}
void getintegrate(int *A,int *C,int n){
for(int i=;i<n;i++)C[i]=(long long)A[i-]*qpow(i,p-,p)%p;
C[]=;
}
int qpow(int a,int b,int p){
int ans=;
for(;b;b>>=,a=(long long)a*a%p)if(b&)ans=(long long)ans*a%p;
return ans;
}

COGS 有标号的二分图计数系列的更多相关文章

  1. COGS 2392 2393 2395 有标号的二分图计数

    有黑白关系: 枚举左部点(黑色点),然后$2^{i*(n-i)}$处理方法同:COGS 2353 2355 2356 2358 有标号的DAG计数 无关系: 发现,假设$f(i)$是一个连通块,对于一 ...

  2. cogs [HZOI 2015]有标号的二分图计数

    题目分析 n个点的二分染色图计数 很显然的一个式子 \[ \sum_{i=0}^n\binom{n}{i}2^{i(n-i)} \] 很容易把\(2^{i(n-i)}\)拆成卷积形式,前面讲过,不再赘 ...

  3. 有标号的DAG计数系列问题

    传送门 II 设 \(f_i\) 表示 \(i\) 个点的答案 那么枚举至少 \(j\) 个点的出度为 \(0\) \[\sum_{j=0}^{i}(-1)^j\binom{i}{j}f_{i-j}2 ...

  4. COGS 2353 2355 2356 2358 有标号的DAG计数

    不用连通 枚举入度为0的一层 卷积 发现有式子: 由$n^2-i^2-(n-i)^2=2*i*(n-i)$ 可得$2^{i*(n-i)}=\frac{{\sqrt 2}^{(n^2)}}{{\sqrt ...

  5. 有标号的DAG计数(FFT)

    有标号的DAG计数系列 有标号的DAG计数I 题意 给定一正整数\(n\),对\(n\)个点有标号的有向无环图(可以不连通)进行计数,输出答案\(mod \ 10007\)的结果.\(n\le 500 ...

  6. COGS 2396 2397 [HZOI 2015]有标号的强连通图计数

    题意:求n个点有向图其中SCC是一个的方案数 考虑求出若干个不连通的每个连通块都是SCC方案数然后再怎么做一做.(但是这里不能用Ln,因为推不出来) 设$f_n$为答案, $g_n$为n个点的有向图, ...

  7. COGS 有标号的DAG/强连通图计数

    COGS索引 一堆神仙容斥+多项式-- 有标号的DAG计数 I 考虑\(O(n^2)\)做法:设\(f_i\)表示总共有\(i\)个点的DAG数量,转移考虑枚举DAG上所有出度为\(0\)的点,剩下的 ...

  8. COGS2356 【HZOI2015】有标号的DAG计数 IV

    题面 题目描述 给定一正整数n,对n个点有标号的有向无环图进行计数. 这里加一个限制:此图必须是弱连通图. 输出答案mod 998244353的结果 输入格式 一个正整数n. 输出格式 一个数,表示答 ...

  9. COGS2355 【HZOI2015】 有标号的DAG计数 II

    题面 题目描述 给定一正整数n,对n个点有标号的有向无环图(可以不连通)进行计数,输出答案mod 998244353的结果 输入格式 一个正整数n 输出格式 一个数,表示答案 样例输入 3 样例输出 ...

随机推荐

  1. mysql 快照读MVCC

    mysql的读分快照读和当前读 快照读 是指写的同时,读不阻塞,达到并发的作用 这时候的读 是 记录的历史版本,存在于undo里,当然回滚时就的也是这个undo 当执行一条update语句时,记录本身 ...

  2. Oracle WebLogic Server 12c 新特性

    美国时间2011年 12月9日,Oracle公司正式发布WebLogic 12c版本,c是cloud的缩写.截止当前(2013年8月)最新版本为Oracle WebLogic Server 12c ( ...

  3. Python——Django学习笔记

    Django——一个封装好的神奇框架 若本文有任何内容错误,望各位大佬指出批评,并请直接联系作者修改,谢谢!小白学习不易. 一.简要模型 模型类操作数据表: python manage.py shel ...

  4. WinForm之GDI画图步骤

    Graphics g = this.CreateGraphics(); //这句是创建画布g,根据窗体得到窗体的画布 Pen p = new Pen(Color.Red, 2); //这句是创建一个红 ...

  5. oracle12c之三 控制PDB中CPU 资源使用

      CPU资源隔离 数据库中,不同的PDB对主机CPU资源使用要求不同,那么我们就可以使用CDB resourceplans来管理不同pdb对CPU资源的使用. CDB Resource Plans ...

  6. vscode用yuml画类图

    vscode用yuml画类图 最近在找画类图的工具,发现vscode一款插件很好用,还支持markdown.vscode插件中直接搜索yuml安装即可. 文件后缀.yuml. 文件开头第一行这样写// ...

  7. 解决 jenkins 下使用 HTML Publisher 插件后查看 html 报告显示不正常

    查看官方文档后,原来是安全问题所导致的. Jenkins安全默认是将以下功能都关闭了1.javascript2.html上的内置插件3.内置css或从其它站的css4.从其它站的图处5.AJAX 我的 ...

  8. linux下,matplotlib遇到的相关问题以及解决方法

    1.在linux下运行matplotlib程序时,matplotlib的安装. 根据不同的linux系统继续相关安装: Debian / Ubuntu : sudo apt-get install p ...

  9. 在VM虚拟机中彻底删除Linux系统

    前言:很久之前安装了Linux虚拟系统,然后用户名忘记了,想着重新安装个Ubuntu系统,就想着删除以前的系统. 删除方法如下: 1.点击打开该Linux系统. 2. 点击虚拟机的左上方“虚拟机”-& ...

  10. 使用kerl安装erlang遇到的问题及解决办法-bak

    1 需要安装相关包 -dev autoconf 2 出现下面错误 * documentation : * xsltproc is missing. * fop is missing. * xmllin ...