前言

五一网课的例题,但是网上没有详细的题解(真的连题解都找不到啊),所以来写一篇,就当攒 RP 了。题目可以在这里提交。原题是 TopCoder - 10947,但是有了账号也交不了?

题目简述

有 \(n\) 张卡片,正面和反面分别组成了 \(1 \sim n\) 的排列。现在你需要将这 \(n\) 张卡片排成一排。卡片可以以任何顺序放置,每张卡片可以显示正面或背面,排成的序列不一定是一个排列。两种方案至少存在一个位置的数字不同,则这两种方案被认为是不同的。求排成的不同的序列的方案数,答案对 \(10^9+7\) 取模。

题目分析

套路地,把卡牌当做边,正面连向反面,建图。发现形成了若干个环。环之间互不影响,所以我们只要求得一个环的方案数 \(W_i\) 即可。进而发现设环的长度为 \(L_i\),则 \(W_i\) 只跟 \(L_i\) 有关,即 \(W_i = f(L_i)\)。

考虑计算 \(f(L)\)。发现方案数和重合的数字个数有关,而每个数字要么出现一次,要么出现两次。故枚举有 \(i\) 个数字出现了两次,求出方案数,总方案数即为所有情况之积。从 \(L\) 个位置中选出 \(2i\) 个位置是重复的,方案数是 \(C_L^{2i}\),若 \(i \neq 0\),则还要乘 \(2\),因为将方案取反可以得到新的方案。接下来,不断从剩下可选的位置中选出重复的那 \(2\) 个位置,这 \(2\) 个位置没有区分。剩下的数随随便排列,方案数是 \((L-2i)!\)。这里方案数是 \(\prod \limits _ {j = 1} ^ {i} C _ {L - 2(j-1)} ^ 2\),化简得 \(\cfrac{n!}{2^i \times (L-2i)!}\)。综上:

\[
f(L) = \sum \limits _ {i = 0} ^ {\left \lfloor \cfrac{L}{2} \right \rfloor} C_L^{2i} \times (2 - [i = 0]) \times \cfrac{L!}{2 ^ i}

\]

故总答案:

\[
ans = \Large \prod \limits _ {i = 1} ^ {cnt} C_{n - \sum \limits _ {j = 1} ^ {i - 1} L_j}^{L_i} \times f(L_i)

\]

总体时间复杂度是 \(\Theta(n)\) 的。

代码

//#pragma GCC optimize(3)
//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx", "sse2", "sse3", "sse4", "mmx")
#include <iostream>
#include <cstdio>
#define debug(a) cerr << "Line: " << __LINE__ << " " << #a << endl
#define print(a) cerr << #a << "=" << (a) << endl
#define file(a) freopen(#a".in", "r", stdin), freopen(#a".out", "w", stdout)
#define main Main(); signed main(){ return ios::sync_with_stdio(0), cin.tie(0), Main(); } signed Main
using namespace std; const int mod = 1000000007;
const int inv2 = 500000004; inline int add(int a, int b){
return a + b >= mod ? a + b - mod : a + b;
} inline int mul(int a, int b){
return 1ll * a * b % mod;
} const int N = 100010; int n, a[N], b[N], trans[N], f[N];
int frac[N], Inv[N], finv[N];
bool vis[N]; inline int C(int n, int m){
return mul(frac[n], mul(finv[m], finv[n - m]));
} inline int calc(int n){
if (f[n]) return f[n];
int res = 0;
for (int i = 0, mu = 1; i <= n / 2; mu = mul(mu, inv2), ++i){
int z = C(n, i << 1);
if (i > 0) z = mul(z, 2);
z = mul(z, mul(frac[n], mu));
res = add(res, z);
}
return f[n] = res;
} signed main(){
scanf("%d", &n);
for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
for (int i = 0; i < n; ++i) scanf("%d", &b[i]), trans[a[i] - 1] = b[i] - 1;
frac[0] = 1, finv[0] = 1;
for (int i = 1; i <= n; ++i) frac[i] = mul(frac[i - 1], i), Inv[i] = i == 1 ? 1 : mod - mul(mod / i, Inv[mod % i]), finv[i] = mul(finv[i - 1], Inv[i]);
int res = 1;
for (int i = 0, j, l = 0, r = n; i < n; ++i) if (!vis[i]){
for (j = i, l = 0; !vis[j]; ++l, vis[j] = true, j = trans[j]);
res = mul(mul(res, C(r, l)), calc(l)), r -= l;
}
printf("%d\n", res);
return 0;
}

Two Sided Cards 题解的更多相关文章

  1. CF949E Binary Cards 题解

    题面 首先发现:一个数最多会出现1次: 然后深入推出:一个数不会既用它又用它的相反数: 这样就可以依次考虑每一位了: 如果所有的数都不含有这一位,那么就直接把所有的数除以2 如果含有,那么就减去这一位 ...

  2. CF908A New Year and Counting Cards 题解

    Content 有 \(n\) 张卡牌,每张卡牌上只会有大小写字母和 \(0\sim 9\) 的阿拉伯数字.有这样一个描述:"如果卡牌正面写有元音字母(\(\texttt{A,E,I,O,U ...

  3. CF701A Cards 题解

    Content 有一个长度为 \(n\) 的数组 \(a_1,a_2,a_3,...,a_n\),试在其中找到 \(\dfrac{n}{2}\) 对数,使得每个数对的元素的和都相等. 数据范围:\(2 ...

  4. luogu P1446 [HNOI2008]Cards

    题目链接 luogu P1446 [HNOI2008]Cards 题解 题意就是求染色方案->等价类 洗牌方式构成成了一个置换群 然而,染色数限制不能用polay定理直接求解 考虑burnsid ...

  5. [Codeforces 864A]Fair Game

    Description Petya and Vasya decided to play a game. They have n cards (n is an even number). A singl ...

  6. Codeforces 744C Hongcow Buys a Deck of Cards 状压dp (看题解)

    Hongcow Buys a Deck of Cards 啊啊啊, 为什么我连这种垃圾dp都写不出来.. 不是应该10分钟就该秒掉的题吗.. 从dp想到暴力然后gg, 没有想到把省下的红色开成一维. ...

  7. CF815D Karen and Cards 官方题解翻译

    看到这道题,网上没有中文版的官方题解,于是就自己翻译了一遍. 不是机器翻译,是一个字一个字纯手翻译的,如果有错误欢迎指正. 比如我们有一张卡片,三个参数分别是 a1 = 4, b1 = 2, c1 = ...

  8. 题解 CF546C 【Soldier and Cards】

    思路 是一道水题,可以用队列+模拟来写,注意不要拿完队列中的元素! 代码 #include<iostream> #include<cstdio> #include<que ...

  9. CF254A Cards with Numbers 题解

    Content 有 \(2n\) 个数,让你找出两两相等的 \(n\) 对数的编号,或者方案不存在. 数据范围:\(1\leqslant n\leqslant 3\times 10^5,1\leqsl ...

  10. bzoj 1004 Cards

    1004: [HNOI2008]Cards Description 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Sun有 多少种染色方案,Sun ...

随机推荐

  1. 在线Token、随机密码生成工具

    在线生成自定义长度,包含大写或小写字母.数字或符号的随机字符串.无论你需要生成API访问令牌.账户激活令牌,还是随机密码字符串,它都能帮你快速完成. 在线Token.随机密码生成工具

  2. 订单推送设计思路-基于支付ID而不是订单号来推送

    订单推送设计思路-基于支付ID而不是订单号来推送 方案:不是基于订单号来核销和分账的,抖音是基于每一笔抖音支付来做订单推送,核销和分账现象:这样会在抖音的订单中心中会出现很多条订单推送的记录. 抖音A ...

  3. 洛谷 P4913 二叉树深度

    题目链接:二叉树深度 思路 存储二叉树的各个节点并递归搜索二叉树深度. 题解 #include <bits/stdc++.h> using namespace std; #define l ...

  4. 华为交换机配置端口模式时报错:Please renew the default configurations

    场景 在华为交换机上使用混杂端口时报这个错,原因是你之前已经将此端口加入了某个vlan 所以你需要undo之前配置的命令 解决方法 sys int G 0/0/1 #替换为报错的端口 undo por ...

  5. mermaid语法画图

    mermaid 脚本语言 graph TB 从上到下 graph BT 从下到上 graph RL 从右到左 graph LR 从左到右 graph LR; A001-->B001; graph ...

  6. 【ClickHouse】5:clickhouse集群部署

    背景介绍: 有三台CentOS7服务器安装了ClickHouse HostName IP 安装程序 程序端口 centf8118.sharding1.db 192.168.81.18 clickhou ...

  7. ubuntu22 flask项目 pyinstaller打包后运行报错: jinja2.exceptions.TemplateNotFound: index.html 的一种解决方案

    前言 有一个flask项目a.py, 目录结构如下: |- a.py |- templates | - index.html |- static |- images 运行 python3 a.py可以 ...

  8. 常回家看看之off_by_null(堆篇)

    上次介绍了堆里面的off_by_one,那么这个off_by_null和它有神马区别呢,哎,别看名字挺像,它俩无论是在栈里面还是堆里面都有很大区别的. off_by_one,这个我们知道可以通过溢出控 ...

  9. cf edu 133 D

    题意 思路 根据题意,最开始可以想到一个二维的dp状态 用dp[i][j]表示跳了j次刚好到i的方案数 如果是跳了j次,那么这次应该要被k+j-1整除才行 那么这样状态转移就是 dp[i][j] = ...

  10. SQL Server大量插入 Java

    在Java中向数据库执行大量插入操作,通常需要考虑性能和效率.对于大量数据的插入,有几种方法可以提高性能,比如使用批处理(Batch Insert).JDBC的批处理API.或者使用SQL Serve ...