前言

五一网课的例题,但是网上没有详细的题解(真的连题解都找不到啊),所以来写一篇,就当攒 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. Task - lmdeploy

    基础作业: 使用 LMDeploy 以本地对话.网页Gradio.API服务中的一种方式部署 InternLM-Chat-7B 模型,生成 300 字的小故事(需截图

  2. MySQL where 操作符

    MySql WHERE 操作符号 前言 在 WHERE 子句中,你可以使用任何条件对记录进行过滤. 准备工作 准备 users 表,并插入数据 # 创建用户表 users create table u ...

  3. 关于编译告警 C4819 的完整解决方案 - The file contains a character that cannot be represented in the current code page (number). Save the file in Unicode format to prevent data loss.

    引言 今天迁移开发环境的时候遇到一个问题,同样的操作系统和 Visual Studio 版本,原始开发环境一切正常,但是迁移后 VS 出现了 C4819 告警,上网查了中文的一些博客,大部分涵盖几种解 ...

  4. 关于vue中image控件,onload事件里,event.target 为null的奇怪问题探讨

    废话不多说(主要文笔比较差),直接上代码 一个简单的demo,如下 <img :src="orginalImgSrc" style="display: none;& ...

  5. MegaCli命令使用整理

    1. 软件安装 rpm -ivh Lib_Utils-1.00-09.noarch.rpm rpm -ivh MegaCli-8.02.21-1.noarch.rpm 2. 常用命令 /opt/Meg ...

  6. C# pythonnet(2)_傅里叶变换(FFT)

    Python代码如下 import pandas as pd import numpy as np import matplotlib.pyplot as plt # 读取数据 data = pd.r ...

  7. C语言自动编译执行脚本

    C语言自动编译执行脚本 在Linux上面用命令行写一些简单的C语言程序,总是遇到一个问题,代码写完后要先编译后运行,而且编译生成的可执行文件默认还是a.out,自己去加参数去改有觉得十分麻烦,所以干脆 ...

  8. SQLServer统计采集数据库相关信息

    在MS Sql Server中可以能过以下的方法查询出磁盘空间的使用情况及各数据库数据文件及日志文件的大小及使用利用率: 1.查询各个磁盘分区的剩余空间:Exec master.dbo.xp_fixe ...

  9. Centos7安装nacos详细步骤(配置开机自启)

    Nacos 解压文件 创建数据库nacos,导入nacos的sql文件 创建数据库nacos,导入nacos的sql文件 修改启动文件(根据系统选择) [root@localhost bin]# cd ...

  10. 前端:如何让background背景图片进行CSS自适应

    在设置login背景时,找到了一张这样的图片: 但是设置成login背景时,如果没有做一些css适应设置,图片就变样了,变成了这样: 严重变形了,这就造成了一种理想与现实的差距. 若想解决这个自适应问 ...