前言

五一网课的例题,但是网上没有详细的题解(真的连题解都找不到啊),所以来写一篇,就当攒 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. vite+vue3+ts+elementPlus前端框架搭建 [三] router路由管理

    路由包括动态路由.静态路由两种,本文中以静态路由的方式实现了动态路由. 1. 创建Router 在Src目录下创建router文件夹,并在router文件夹下创建index.ts文件. index.t ...

  2. MongoDB文档存储

    非关系型数据库存储 NoSQL,全称 Not Only SQL,意为不仅仅是 SQL,泛指非关系型数据库.NoSQL 是基于键值对的,而且不需要经过 SQL 层的解析,数据之间没有耦合性,性能非常高. ...

  3. 使用 Spring 实现控制反转和依赖注入

    使用 Spring 实现控制反转和依赖注入 概述 在本文中,我们将介绍IoC(控制反转)和DI(依赖注入)的概念,以及如何在Spring框架中实现它们. 什么是控制反转? 控制反转是软件工程中的一个原 ...

  4. QT6设置应用程序图标

    准备好一个ico格式的图标, 放到源码文件中, 比如放在 resources/logo.ico 在源码目录中新建一个icon.rc的文件, 内容如下: IDI_ICON1 ICON DISCARDAB ...

  5. LED虚拟拍摄-跟踪算法

    LED虚拟拍摄-跟踪算法 图引用拍摄黑科技,LED虚拟影棚揭秘 标定流程 上面是一台Track设备,现精度比较高的主要是Redspy,Mosys,一般影视用这二种,其底层技术参考SMAL单目+惯性传感 ...

  6. 快速调用 GLM-4-9B-Chat 语言模型

    一.确认本机显卡配置 二.下载大模型 国内可以从魔搭社区下载, 下载地址:https://modelscope.cn/models/ZhipuAI/glm-4-9b-chat/files 三.运行官方 ...

  7. 通过vscode写博客

    通过Vscode写博客到博客园 前言 在以前的写作方式都是通过博客园内置的markdown进行工作,但是在实际使用过程中,感觉不是很方便,所以找到了用VSCode插件写作的方法. 所需插件 博客园Cn ...

  8. Vue源码学习(二十):$emit、$on实现原理

    好家伙, 0.一个例子 <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset= ...

  9. Javascript克隆数据

    JS 复制数据 1 浅复制 具体方法 // 数组 Array.prototype.slice // 普通对象 Object.assign 思考 2 深复制 1) function deepClone( ...

  10. 女朋友问我 LB 是谁?

    科普一下 LB(负载均衡)技术 我的编程导航网站:www.code-nav.cn 大家好,我是鱼皮. 周末在家写代码,无意中跟女朋友提了下 LB,还说 LB 好的呱呱叫. 她笑了笑,问我 LB 是谁? ...