传送门.

题解:


4月YY集训时做过DAG计数,和这个基本上是一样的,但是当时好像直接暴力子集卷积,不然我省选时不至于不会,这个就多了个边不选的概率和子集卷积。

DAG计数是个套路来的,利用的是DAG中入度为0的点。

设\(f[S]\)表示只考虑s里的点的诱导子图形成DAG的方案数。

枚举一个\(T|S~\and~T=\empty\),这个T就是新的图中度数为0的点,首先它们之间要没有边,然后\(T\)和\(S\)间的边要么没有,要么都由\(T->S\),记\(cnt[S]\)表示S里的边数,这转移系数是:

\({1\over 3}^{g[T]}*{{2\over 3}^{g[S+T]}\over {2\over 3}^{g[S]+g{T}}}\)

注意这样会算重,因为会枚举到度数为0的点的子集,那么容斥系数\((-1)^{|T|+1}\),考虑用\(\sum_{i=1}^{|T|}(-1)^{i+1}*C_{|T|}^i=1\)来证明。

直接卷积是\(O(3^n)\),然后就上or FWT + 1的个数的老套路了,复杂度\(O(2^n*n^2)\)。

Code:


#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, B = y; i <= B; i ++)
#define ff(i, x, y) for(int i = x, B = y; i < B; i ++)
#define fd(i, x, y) for(int i = x, B = y; i >= B; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std; const int mo = 998244353; ll ksm(ll x, ll y) {
ll s = 1;
for(; y; y /= 2, x = x * x % mo)
if(y & 1) s = s * x % mo;
return s;
} const ll w1 = ksm(3, mo - 2), w2 = 2 * ksm(3, mo - 2) % mo;
const ll nw1 = ksm(w1, mo - 2), nw2 = ksm(w2, mo - 2); const int N = 21; const int M = 1 << 20;
int n, m, x, y, a2[N];
int bz[N][N];
ll f[M], nf[M], g[M];
int cnt[M]; void dft(int *a, int n, int f) {
for(int h = 1; h < n; h *= 2) for(int j = 0; j < n; j += 2 * h) ff(i, 0, h) {
if(f == 1) a[i + j + h] = (a[i + j + h] + a[i + j]) % mo; else
a[i + j + h] = (a[i + j + h] - a[i + j]) % mo;
}
} int a[21][M], b[21][M]; int main() {
scanf("%d %d", &n, &m);
a2[0] = 1; fo(i, 1, n) a2[i] = a2[i - 1] * 2;
fo(i, 1, m) {
scanf("%d %d", &x, &y);
x --; y --;
bz[x][y] = 1;
}
ff(s, 1, a2[n]) cnt[s] = cnt[s - (s & -s)] + 1;
ff(s, 0, a2[n]) {
f[s] = g[s] = nf[s] = 1;
if(s == 0) continue;
int st;
ff(i, 0, n) if(s >> i & 1) { st = i;}
f[s] = f[s ^ (1 << st)];
g[s] = g[s ^ (1 << st)];
nf[s] = nf[s ^ (1 << st)];
ff(i, 0, st) if(s >> i & 1) {
if(bz[st][i]) f[s] = f[s] * w2 % mo, nf[s] = nf[s] * nw2 % mo, g[s] = g[s] * w1 % mo;
if(bz[i][st]) f[s] = f[s] * w2 % mo, nf[s] = nf[s] * nw2 % mo, g[s] = g[s] * w1 % mo;
}
}
fo(i, 1, n) {
ff(j, 0, a2[n]) if(cnt[j] == i)
b[i][j] = nf[j] * g[j] % mo * ((cnt[j] & 1) ? 1 : -1);
dft(b[i], a2[n], 1);
}
a[0][0] = 1; dft(a[0], a2[n], 1);
fo(w, 0, n) {
fo(j, 1, n - w) {
ff(i, 0, a2[n]) a[j + w][i] = ((ll) a[w][i] * b[j][i] + a[j + w][i]) % mo;
}
}
dft(a[n], a2[n], -1);
ll ans = a[n][a2[n] - 1];
ans = (ans % mo + mo) * f[a2[n] - 1] % mo;
pp("%lld\n", ans);
}

Comet Contest#11 F arewell(DAG计数+FWT子集卷积)的更多相关文章

  1. 有标号DAG计数 [容斥原理 子集反演 组合数学 fft]

    有标号DAG计数 题目在COGS上 [HZOI 2015]有标号的DAG计数 I [HZOI 2015] 有标号的DAG计数 II [HZOI 2015]有标号的DAG计数 III I 求n个点的DA ...

  2. CF838C(博弈+FWT子集卷积+多项式ln、exp)

    传送门: http://codeforces.com/problemset/problem/838/C 题解: 如果一个字符串的排列数是偶数,则先手必胜,因为如果下一层有后手必赢态,直接转移过去,不然 ...

  3. CF914G Sum the Fibonacci (快速沃尔什变换FWT + 子集卷积)

    题面 题解 这是一道FWT和子集卷积的应用题. 我们先设 cnt[x] 表示 Si = x 的 i 的数量,那么 这里的Nab[x]指满足条件的 Sa|Sb=x.Sa&Sb=0 的(a,b)二 ...

  4. 「CometOJ」Contest #11

    Link Aeon 显然字典序最大就是把最小的字母放在最后 Business [动态规划] 简单dp dp[i][j]dp[i][j]dp[i][j]表示到第iii天,当前有jjj块钱,最后返还的钱最 ...

  5. Comet OJ - Contest #11 题解&赛后总结

    Solution of Comet OJ - Contest #11 A.eon -Problem designed by Starria- 在模 10 意义下,答案变为最大数的最低位(即原数数位的最 ...

  6. Comet OJ - Contest #11题解

    传送门 \(A\) 咕咕咕 const int N=1e6+5; char s[N],t[N];int n,res; inline bool cmp(const int &x,const in ...

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

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

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

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

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

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

随机推荐

  1. 【JZOJ1913】【BZOJ2124】等差子序列

    description 给一个1到N的排列{Ai},询问是否存在1<=p1<p2<p3<p4<p5<-<pLen<=N (Len>=3), 使得A ...

  2. 二分图最大权匹配——KM算法

    前言 这东西虽然我早就学过了,但是最近才发现我以前学的是假的,心中感慨万千(雾),故作此篇. 简介 带权二分图:每条边都有权值的二分图 最大权匹配:使所选边权和最大的匹配 KM算法,全称Kuhn-Mu ...

  3. 耗时十个月的德国APS,教会我的学习方法

    考过了准备了10个月的Aps ,想送给关注我的8175个粉丝,一份礼物,感谢你们看的起我,对我的支持和关注. 这份礼物,我就大言不惭的称之为:达令的学习方法. 我的考试经历:高考两次,中戏艺考三试,导 ...

  4. ROM、PROM、EPROM、EEPROM、Flash ROM分别指什么?

    ROM指的是“只读存储器”,即Read-Only Memory.这是一种线路最简单半导体电路,通过掩模工艺, 一次性制 造,其中的代码与数据将永久保存(除非坏掉),不能进行修改.这玩意一般在大批量生产 ...

  5. JS-模拟printf

    function printf(){ var args = [].slice.call(arguments), fmt = args.shift(), args_index = 0; ///%(填充的 ...

  6. 86、使用Tensorflow实现,LSTM的时间序列预测,预测正弦函数

    ''' Created on 2017年5月21日 @author: weizhen ''' # 以下程序为预测离散化之后的sin函数 import numpy as np import tensor ...

  7. git和svn的比较

    当前的市场上主流的两种项目开发版本控制软件就是Git和SVN,那么这二者到底有什么区别呢? 在我们公司,其实两个都用,跟对个人体验,我觉得两者差不多,都是进行代码的版本管理. 我觉得1.由于我是实习生 ...

  8. 3.Jmeter 快速入门教程(三-1) --添加响应断言(即loadrunner中所指的检查点)

    上一节课,我们创建了一个测试场景,并进行了少量vuser的负载测试. 有时候我们执行了测试,但是发现并不是所有事务都执行成功了. 那是因为我们只是发起了测试,但并没有对每次请求测试的返回作校验. 所以 ...

  9. SpringMVC入门及拦截器

    SSM最后一个框架springmvc,其实上手特别简单.但是我昨天看一个深入源码的视频,差点GG.其实以前学过很多东西,都忘了,不敢说学会,现在有了本书,看过一遍之后.多多少少记住一些,权当我会用了, ...

  10. UML各种线的含义

    内容目录: 从一个示例开始 类之间的关系 时序图 附录:<图说设计模式> 看懂UML类图和时序图 这里不会将UML的各种元素都提到,我只想讲讲类图中各个类之间的关系: 能看懂类图中各个类之 ...