各种网站名称大全,电子商务网站建设实训总结,商务 服务类网站模板,青山网站建设题目
一个长为n(n30)的原始序列x#xff0c;x[i]可以取值0或1
一个长为m(m1e9)的点对序列(s,t)#xff0c;
s序列第i项和t的第i项#xff0c;均可以取值[1,n]#xff0c;
如果构造好s和t后#xff0c;对任意都存在01序列x使得#xff0c;
则称这个序列是合法…题目
一个长为n(n30)的原始序列xx[i]可以取值0或1
一个长为m(m1e9)的点对序列(s,t)
s序列第i项和t的第i项均可以取值[1,n]
如果构造好s和t后对任意都存在01序列x使得
则称这个序列是合法的问种(s,t)序列中有多少合法序列
答案对998244353取模
思路来源
官方题解
https://www.cnblogs.com/chasedeath/p/14567667.html
题解
考虑1-n共n个点的不含自环的有向图条边如果可以用(i,j)边表示
而最终x是要被化成两堆的一堆0一堆1也就是一个二分图
要求二分图的某一个带标号的边集方案只能被计一次
有向图不好统计可以考虑看成无向图也就是(1,2)和(2,1)看成一种边
最后填入m个位置后再决定翻不翻转再乘上对应的种选法
所以需要统计的是有标号二分图的方案数
有标号二分图计数
计表示i个点j条边的二分图方案数允许重复 即枚举二分图左边选了k个点右边选了i-k个点k*(i-k)条边里选j条
这样的话一个有着t个连通块的二分图会被计数次
因为对应连通块部分可以左右互换从而在另一种合法答案中被统计到 于是考虑怎么去重 计表示i个点j条边连通的二分图
然而连通块数定义在状态里不好用于转移所以后续的计数考虑容斥
通过减掉不合法的方案
即枚举最后一个点所在的连通块多大
对应连通块和之前的二分图是在什么时候断裂的
当大小为k时从i-1个点中选k-1个点再对应选出一些边
有 有了联通的二分图之后再考虑如何合并
如上文所说一个有着t个连通块的二分图会被计数次
而h方案是连通的即一个连通块会被计数2次
左右各一次所以除以2是实际的方案数 计表示i个点j条边由若干个连通块组成、无重复的二分图
转移仍然枚举最后一个点所在的连通块多大
从之前的f合法方案通过背包转移到新的合法方案
当大小为k时从i-1个点中选k-1个点再对应选出一些边
有 求出f[i][j]后n个点是固定的
因为f[n-1][j]可以通过不用边的方式转移到f[n][j]
所以只需要用到f[n][j]的状态无需再遍历f[in][j]的值
当有j条边时需要满足j条边填到m个位置j条边都至少出现一次不然计数就会有重复
小球放盒问题
方法一
这等价于m个有区别的小球放入j个有区别的盒子每个盒子不能为空
而第二类斯特林数S(m,j)为m个有区别的小球放入j个无区别的盒子的方案数
所以求出乘上j个盒子的顺序即可代码中用dp2[i]表示
方法二
互换小球和盒子
dp[i]表示恰有i种球被放到了m个盒子里每个盒子只能放一个球
那么就需要用全量的情况减掉不合法的情况
有
代码
// Problem: G - Many Good Tuple Problems
// Contest: AtCoder - HHKB Programming Contest 2023(AtCoder Beginner Contest 327)
// URL: https://atcoder.jp/contests/abc327/tasks/abc327_g
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)#includebits/stdc.h
using namespace std;
#define rep(i,a,b) for(int i(a);i(b);i)
#define per(i,a,b) for(int i(a);i(b);--i)
typedef long long ll;
typedef double db;
typedef pairll,int P;
#define fi first
#define se second
#define pb push_back
#define dbg(x) cerr(#x):x ;
#define dbg2(x) cerr(#x):xendl;
#define SZ(a) (int)(a.size())
#define sci(a) scanf(%d,(a))
#define scll(a) scanf(%lld,(a))
#define pt(a) printf(%d,a);
#define pte(a) printf(%d\n,a)
#define ptlle(a) printf(%lld\n,a)
#define debug(...) fprintf(stderr, __VA_ARGS__)
const int N31,MN*N,mod998244353,inv2(mod1)/2;
int t,n,m,f[N][M],g[N][M],h[N][M],c[M][M],dp[M],dp2[M];
void ADD(int x,int y){x(xy)%mod;
}
int modpow(int x,int n,int mod){int res1;for(;n;n1,x1ll*x*x%mod){if(n1)res1ll*res*x%mod;}return res;
}
int C(int x,int y){if(x0 || y0 || xy)return 0;return c[x][y];
}
void sol(){sci(n),sci(m);c[0][0]1;rep(i,1,M-1){c[i][0]c[i][i]1;rep(j,1,i-1){c[i][j](c[i-1][j]c[i-1][j-1])%mod;}}rep(i,1,M-1){dp[i]modpow(i,m,mod);rep(j,1,i-1){ADD(dp[i],mod-1ll*c[i][j]*dp[j]%mod);}//printf(i:%d f:%d\n,i,dp[i]);}rep(i,1,M-1){rep(j,1,i){int sg((i-j)1)?-1:1;ADD(dp2[i],(1ll*sg*C(i,j)%mod*modpow(j,m,mod)%mod)%mod);}//printf(i:%d f:%d\n,i,dp2[i]);}int ans0;rep(i,1,n){int upi*(i1)/4;rep(j,0,up){rep(k,0,i){ADD(g[i][j],1ll*C(i,k)*C(k*(i-k),j)%mod);}h[i][j]g[i][j];rep(k,1,i-1){rep(l,0,j){ADD(h[i][j],mod-1ll*C(i-1,k-1)*h[k][l]%mod*g[i-k][j-l]%mod);}}f[i][j]1ll*h[i][j]*inv2%mod;rep(k,1,i-1){rep(l,0,j){ADD(f[i][j],1ll*C(i-1,k-1)*h[k][l]%mod*f[i-k][j-l]%mod*inv2%mod);}}//printf(i:%d j:%d 1:%d 2:%d 3:%d\n,i,j,g[i][j],h[i][j],f[i][j]);//printf(i:%d j:%d f:%d\n,i,j,f[i][j]);//if(in jm)printf(i:%d j:%d f:%d dp:%d add:%d\n,i,j,f[i][j],dp[j],1ll*f[i][j]*dp[j]%mod);if(in)ADD(ans,1ll*f[i][j]*dp[j]%mod);}}//pte(ans);ans1ll*ans*modpow(2,m,mod)%mod;pte(ans);
}
int main(){t1;//sci(t); // t1while(t--){sol();}return 0;
}