[AGC030F] Permutation and Minimum
又被计数题创思力。
Description
Solution
考虑建立图论模型:建立一张包含 个点的图,将所有 连边。
首先,考虑一种连边会对应多少种不同的 。为方便叙述,我们称 被确定,当且仅当 在 中的位置已确定。
显然,若 中只有 ,那么可以将所有边的左端点任意排列,有 种方案,对应 种不同的 。对于一般情况,我们先删去所有两端均确定的边(对于所有满足 均确定的 ,将 两点一同删去),然后将剩余的点重编号,并将边分为两类:
- 两端 一者被确定(称其为一类边)。此时, 在 中的位置已被确定。
- 两端 均未被确定(称其为二类边)。此时,这些 可以在 中任意排列,产生 的贡献,其中 表示这样的 的数量。
注意到 即为满足 的 的数量,与具体连边无关。最后计算答案时乘上即可。
但答案显然不是连边方案数 ,因为可能存在本质相同的连边方案。具体来说,两种连边方案本质不同,当且仅当:
- 所有二类边的左端点组成的可重集不同。
- 存在被确定的 ,使得包含 的一类边的左端点不同。
现在,我们的任务是:计算本质不同的连边方案数。
考虑从后往前 ,令 表示,看了编号 的点,其中有 个被确定的点尚未匹配,有 个未被确定的点尚未匹配。转移考虑如下五种情况:
- 未被确定
- 匹配一个未被确定的点,相当于在可重集中加入 ,转移到 。
- 匹配一个被确定的点,根据之前 本质不同 的定义,我们关心其另一端的确定点,因此以 的转移系数转移到 。
- 暂时不匹配 ,转移到 。
- 被确定。
- 匹配一个未被确定的点,此时以 为一端的一类边的左端点必然是 ,我们并不关心其另一端的不确定点,因此直接转移到 。
- 匹配一个被确定的点,这是不可能的。
- 暂时不匹配 ,转移到 。
边界:。
答案:。
转移是 的,时间复杂度 ,可以通过本题。
Code
#include <bits/stdc++.h>
#define int long long
#define inf 8200000000000000000
using namespace std;
const int N=605,mod=1e9+7;
int read(){
int s=0,w=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') w=-w;ch=getchar();}
while (ch>='0'&&ch<='9'){s=(s<<1)+(s<<3)+(ch^'0');ch=getchar();}
return s*w;
}
int n,m,sz,ckp[N],f[N][N],g[N][N],vis[N];
void chkadd(int x,int &y){y+=x;if(y>inf)y%=mod;}
void Swap(int &x,int &y){
if (y) y%=mod;
x=y,y=0;
}
signed main(){
n=read();
for (int i=1;i<=n;i++){
int x=read(),y=read();
if (x<0&&y<0) sz++;
else if (x>0&&y>0) vis[x]=vis[y]=2;
else if (x>0) vis[x]=1;
else vis[y]=1;
}
for (int i=1;i<=(n<<1);i++){
if (vis[i]<2) ckp[++m]=i;
}
sort(ckp+1,ckp+m+1,greater<int>()),f[0][0]=1;
for (int t=1;t<=m;t++){
bool typ=vis[ckp[t]];
for (int x=0;x<=min(n,t-1);x++){
for (int y=0,R=min(t-1-x,n);y<=R;y++){
int val=f[x][y];
if (!val) continue;
if (!typ){
if (x) chkadd(val*x,g[x-1][y]);
if (y) chkadd(val,g[x][y-1]);
chkadd(val,g[x][y+1]);
}
else{
if (y) chkadd(val,g[x][y-1]);
chkadd(val,g[x+1][y]);
}
}
}
for (int x=0;x<=min(n,t);x++){
for (int y=0,R=min(t-x,n);y<=R;y++) Swap(f[x][y],g[x][y]);
}
}
int ans=f[0][0];
for (int i=1;i<=sz;i++) ans=(ans*i)%mod;
return cout<<ans,0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通