1 条题解
-
0
自动搬运
来自洛谷,原作者为

Demeanor_Roy
小时候我们总想去改变别人,后来发现,比起改变,筛选是性价比更高的事。搬运于
2025-08-24 22:47:48,当前版本为作者最后更新于2023-02-19 16:55:45,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
- 出题人题解。
第一档考虑手玩或爆搜,接下来从第二档讲起。
考虑图 上若存在三点 ,若满足 有边,且 有边,那么我们只需改变 的有无边情况,即有边就删无边就加,就能构造出与 本质相同的图。那么我们似乎可以得出,图 是单图当且仅当其所有点入度为 或出度为 。
可这是有问题的,因为存在一个反例,即两点环。不难发现若图中一两点环与外界不联通,显然也无法据此构造出与其本质相同的图。所以需分两种情况讨论。
思考如何计数,对于一个 个点的图。令 表示 个点的单图数, 表示 个点不考虑两点环的单图数, 表示 个点只考虑两点环的单图数。显然有:
先思考 的求解。因为 表示的是 个点划分成 对两点环的方案数,我们不妨考虑一对一对选取,那么方案数就是 。但这样做会算重,因为其实是与顺序无关的,所以再除以一个 即可。化简后可得 。
那么 怎么求呢?由于所有点要么无入度,要么无出度。考虑这样一种刻画:我们将所有点分为有入度和无入度两类,若前者有 个点,则对于前者可能有 条边,其中一条边都没有是非法的,故有 种方案,将所有点的方案合并,故此时方案数为 。所以可得:
故暴力求解可做到 。预处理 即可做到 。
显然可以优化到 。
不过并不美丽也无甚价值。代码:
#include<bits/stdc++.h> using namespace std; #define LL long long const int N=1010; int T,n,mod,fct[N],ans[N],C[N][N]; inline int pwr(int x,int y) { int res=1; while(y) { if(y&1) res=(LL)res*x%mod; x=(LL)x*x%mod;y>>=1; } return res; } inline void init() { ans[0]=C[0][0]=C[1][0]=C[2][0]=fct[1]=1; for(int i=3;i<N;i++) C[i][0]=1,fct[i]=(i&1?(LL)fct[i-2]*i%mod:0); for(int i=1;i<N;i++) for(int j=1;j<=i;j++) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod; for(int i=1;i<N;i++) for(int j=0;j<i;j++) ans[i]=(ans[i]+(LL)C[i][j]*pwr(pwr(2,i-j)-1,j)%mod)%mod; } inline void solve() { scanf("%d",&n); int res=ans[n]; for(int i=2;i<=n;i+=2) res=(res+(LL)C[n][i]*fct[i-1]%mod*ans[n-i]%mod)%mod; printf("%d\n",res); } int main() { scanf("%d%d",&T,&mod); init(); while(T--) solve(); return 0; }
- 1
信息
- ID
- 8350
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者