首页 > 其他分享 >[省选联考 2024] 重塑时光 题解

[省选联考 2024] 重塑时光 题解

时间:2024-03-10 18:44:16浏览次数:24  
标签:md DAG 省选 题解 子集 s2 联考 dp define

考虑这题是什么意思,其实就是让你把 DAG 划分成若干个集合,点之间连边转化为对应集合之间连边以后图仍然是一个 DAG,然后需要知道划分成了多少个集合,每种集合的个数求出方案数,乘上对应的系数并求和。

系数是很显然的,即:

\[{k+1\choose i}\frac{i!k!}{n!\prod_{i=1}^k (n+i)} \]

考虑怎么求方案数。记 \(f_{S,i}\) 表示把集合 \(S\) 分成 \(i\) 个子集且最终的图是一个 DAG 的方案数。考虑枚举一个没有出边的子集然后转移,这样可以保证最终的图是一个 DAG,但是会算重。

会算重,所以就可以做一个容斥。记 \(g_{S,i}\) 表示把集合 \(S\) 分成 \(i\) 个子集且这些子集之间无边的方案数。可以直接枚举子集然后转移,使得子集中包含 \(S\) 中编号最小的点,这样求出来的方案数是正确的。

然后就是最终的容斥部分,易得:

\[f_{S,i}=\sum_{S'\subseteq S}\sum_{j=1}^{i}(-1)^{j-1}\cdot g_{S',j}\cdot f_{S/S',i-j} \]

最后乘上系数求和即可。时间复杂度
\(T(n)=\sum_{i=0}^n{n\choose i}2^ii^2\mathcal{O}(1)=2\times 3^{n-2}n(2n+1)\mathcal{O}(1)=\mathcal{O}(3^nn^2)\),常数很小,可以通过此题。

参考代码:

#include<bits/stdc++.h>
#define ll long long
#define mxn 200003
#define md 1000000007
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define rept(i,a,b) for(int i=a;i<b;++i)
using namespace std;
inline ll power(ll x,int y){
    ll ans=1;
    for(;y;y>>=1){
        if(y&1)ans=ans*x%md;
        x=x*x%md;
    }
    return ans;
}
int n,m,k,t,d[18],d1[18],dd[1<<15],s[18],a[18],c[20][20];
ll xi,ans,fac[20],dp[1<<15],f1[1<<15][17],f[1<<15][17];
signed main(){
    scanf("%d%d%d",&n,&m,&k);
    c[0][0]=1;
    rep(i,1,18){
        c[i][0]=1;
        rep(j,1,i)c[i][j]=(c[i-1][j-1]+c[i-1][j])%md;
    }
    fac[0]=1;
    rep(i,1,18)fac[i]=fac[i-1]*i%md;
    for(int i=0,x,y;i<m;++i){
        scanf("%d%d",&x,&y);
        x--,y--;
        d[y]|=1<<x,d1[x]|=1<<y;
    }
    xi=1;
    rep(i,1,n)xi=xi*i%md;
    xi=power(xi,md-2);
    rep(i,1,k)xi=xi*power(n+i,md-2)%md*i%md;
    dp[0]=1;
    rept(s,1,1<<n){
        rept(i,0,n)if((s>>i)&1){
            if(d[i]&s)continue;
            dp[s]=(dp[s]+dp[s^(1<<i)])%md;
        }
    }
    rept(s,1,1<<n){
    	rept(i,0,n)if((s>>i)&1){
    		dd[s]=dd[s^(1<<i)]|d[i];
    		break;
		}
	}
    f1[0][0]=1;
    rept(s,1,1<<n){
    	int s1=s^(s&-s),ct=min(__builtin_popcount(s),k+1);
    	for(int s2=s1;;s2=(s2-1)&s1){
    		rept(i,0,n)if(((s2|(s&-s))>>i)&1&&((d[i]|d1[i])&(s1^s2)))goto nxt;
    		rep(i,1,ct)f1[s][i]=(f1[s][i]+f1[s1^s2][i-1]*dp[s2|(s&-s)])%md;
    		nxt:;
    		if(!s2)break;
		}
	}
    f[0][0]=1;
    rept(s,1,1<<n){
    	int ct=min(__builtin_popcount(s),k+1);
    	for(int s1=s;s1;s1=(s1-1)&s){
    		if((s^s1)&dd[s1])continue;
    		rep(i,1,ct){
    			rep(j,1,i){
    				if(j&1)f[s][i]=(f[s][i]+f[s^s1][i-j]*f1[s1][j])%md;
    				else f[s][i]=(f[s][i]-f[s^s1][i-j]*f1[s1][j])%md;
				}
			}
		}
	}
	rep(i,1,k+1)ans=(ans+f[(1<<n)-1][i]*c[k+1][i]%md*fac[i])%md;
    cout<<(ans*xi%md+md)%md;
    return 0;
}

标签:md,DAG,省选,题解,子集,s2,联考,dp,define
From: https://www.cnblogs.com/zifanoi/p/18064562

相关文章

  • [省选联考 2024] 迷宫守卫 题解
    首先Bob肯定是贪心操作,即如果能操作且右儿子中第一个数小于左儿子中的第一个数就一定操作(因为排列中的数两两不同),否则不操作。考虑一个dp,即\(f_{i,j}\)表示\(i\)中的子树操作完以后使得第一个数为\(j\)的最小代价。发现总状态数是\(\mathcalO(2^nn)\)的,对于一个点的......
  • [省选联考 2024] 魔法手杖 题解
    首先有个很显然的\(\mathcalO(nk^2)\)的做法,即二分答案,然后trie树上判断。对于trie树上一颗子树内的判定,考虑当前二分的\(\text{mid}\)这一位是\(1\)还是\(0\)以及\(x\)这一位填什么。对于\(1\)的情况,如果填\(0\),那么右儿子仍然合法,左儿子中的数必须要放到......
  • [省选联考 2024] 季风 题解
    \(\large\textbf{Statement.}\)求出最小的非负整数\(m\),使得:\[\left|x-\sum_{i=0}^{m-1}x_{i\bmodn}\right|+\left|y-\sum_{i=0}^{m-1}y_{i\bmodn}\right|\lemk\]\(\large\textbf{Solution.}\)考虑枚举\(m\bmodn\),然后求和就转化成了一段前缀和加上整个序列和的若......
  • Gym-101915D 题解
    D给定一张图,分为左右各\(P\)个点,左右各自内部是一个完全图,左右之间有\(m\)条边。求这个图的最大团。\(P\le20,m\leP^2\)。对于每个右部点,求出一个长度为\(20\)的二进制数,第\(i\)位是\(1\)表示它与左部第\(i\)点有连边。枚举右部点的子集\(S\),将它们的二进制数......
  • Acwing166 数独题解 - DFS剪枝优化
    166.数独-AcWing题库题意数独是一种传统益智游戏,你需要把一个9×9的数独补充完整,使得数独中每行、每列、每个3×3的九宫格内数字1∼9均恰好出现一次。请编写一个程序填写数独。思路搜索+剪枝(优化搜索顺序、位运算)优化搜索顺序:很明显,我们肯定是从当前能填合法......
  • [ABC219E] Moat 题解
    [ABC219E]Moat题解思路解析一眼看到输入数据只有\(4\)行\(4\)列,直接想到状压枚举。可以直接枚举所有护城河所包含起来的格子,判断是否连通以及判断是否包含住了所有村庄。判断连通我选择用洪水填充,随便选一个包含着的格子,若可以通过当前格移动到所有被包含格就说明连通。以......
  • ABC344G 题解
    ABC344G题解给定平面上\(n\)个点和\(q\)条直线,问对于每条线,有多少点在它上方。形式化的,对于直线\(y=ax+b\)统计有多少点\((x,y)\)满足\(y\geax+b\),即\(-ax+y\geb\)。故我们可以将所有点按照\(-ax+y\)排序,从而利用二分简单的得出结果。但是我们显然不可能暴力进......
  • 洛谷 P1099 题解
    洛谷P1099【NOIP2007提高组】树网的核题意简述给定一棵带边权无根树和一个正整数\(s\)。在这棵树的任意直径上截取一段长度不超过\(s\)的路径\(F\),使离\(F\)最远的点到\(F\)的距离最小,求出这个距离。思路记\(\delta(a,b)\)为\(a,b\)之间的路径。对于任意......
  • 省选联考 2024 重塑时光
    首先原问题显然是一个\(\text{DAG}\)计数的形式,施加枚举\(0\)度点集合\(S\)容斥的技巧是自然的。考虑\(k\)刀将其切割成\(t\)段后最终找到一种标号使得存在一种重排方案使其合法的方案数。段内的方案计算是容易的,要求它们所有关系顺序即可,可以快速求出构成一个段的集合......
  • abc344_D - String Bags 题解
    一个月没有碰oi,感觉水平已经退化到负的了。来复健一下。D-StringBagslink题意:给你\(n\)组字符串组,按\(1\)~\(n\)的顺序,对于每组字符串组,可从中至多选一个字符串。求能否用所选串按顺序拼接成指定串,以及选取字符串的最小个数。然后读完题发现是个\(01\)背包;对于第......