CF 398 E(动态规划)
传送门:
http://codeforces.com/problemset/problem/398/E
题解:
首先答案不超过2。
最长环=1时,ans=0
最长环=2时,ans=1
否则,ans=2
考虑有长度大于2的环时如何两步出解。
那么第一步肯定是把大环拆成若干长度不超过2的环。
不妨确定一个x,设它指向y,指向它的是z,那么肯定将y、z交换,这样x、y在一个环里,然后剩下一个len-2的环,不过因为z不能再动了,所以对这个环的拆分就唯一了,一直下去可以把环拆开,并且只考虑这个环的方案数是len。
有多个环时,这些环的选择时可以相交的。
现在有两个环,
一定有一步交换位于不同环上的两个点,如果依然想拆成若干长度不超过2的环,那么剩下的交换也是唯一的。
由于对称问题,也只有len种。
显然两个环的时候必须长度相等才有解。
然后我并不会证更多环没有解。
然后就可以设个\(f[i][j]\)表示长度为i的有j个环的方案数
\(f[i][j]=f[i][j-1]*i+f[i][j-2]*(j-1)*i\),复杂度是调和级数
那么接下来\(O(k!)\)暴力的话也TLE了。
考虑确定每个点就是把若干条链拼起来,那么就只用集合划分了。
Code:
#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, B = y; i <= B; i ++)
#define ff(i, x, y) for(int i = x, B = y; i < B; i ++)
#define fd(i, x, y) for(int i = x, B = y; i >= B; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std;
const int mo = 1e9 + 7;
ll ksm(ll x, ll y) {
ll s = 1;
for(; y; y /= 2, x = x * x % mo)
if(y & 1) s = s * x % mo;
return s;
}
const int N = 1e6 + 5;
int n, k, a[N], r[N], q[N];
ll fac[15];
vector<ll> f[N], nf[N];
int b[N], b0, cnt[N];
int c[N], c0, d[N];
ll ans, sum, s2;
void dg(int x) {
if(x > b0) {
ll s = sum, s3 = s2;
fo(i, 1, c0) {
s3 += c[i] > 2;
s = s * nf[c[i]][cnt[c[i]]] % mo;
cnt[c[i]] ++;
s = s * f[c[i]][cnt[c[i]]] % mo;
}
ll xs = 1;
fo(i, 1, c0) xs = xs * fac[d[i] - 1] % mo;
ans = (ans + (s3 ? s : 1) * xs) % mo;
fo(i, 1, c0) cnt[c[i]] --;
return;
}
fo(i, 1, c0) {
c[i] += b[x];
d[i] ++;
dg(x + 1);
d[i] --;
c[i] -= b[x];
}
c[++ c0] = b[x]; d[c0] = 1;
dg(x + 1);
d[c0] = 0; c0 --;
}
int main() {
freopen("determination.in", "r", stdin);
freopen("determination.out", "w", stdout);
fac[0] = 1; fo(i, 1, 15) fac[i] = fac[i - 1] * i % mo;
scanf("%d %d", &n, &k);
fo(i, 1, n) scanf("%d", &a[i]), r[a[i]] ++;
fo(i, 1, n) {
f[i].resize(n / i + 1);
nf[i].resize(n / i + 1);
f[i][0] = 1;
fo(j, 1, n / i) {
f[i][j] = f[i][j - 1];
if(j >= 2) f[i][j] = (f[i][j] + f[i][j - 2] * (j - 1)) % mo;
f[i][j] = f[i][j] * i % mo;
}
ll s = 1;
fo(j, 1, n / i) s = s * f[i][j] % mo;
s = ksm(s, mo - 2);
fd(j, n / i, 0) nf[i][j] = s, s = s * f[i][j] % mo;
s = 1;
fo(j, 1, n / i) {
nf[i][j] = nf[i][j] * s % mo;
s = s * f[i][j] % mo;
}
}
fo(i, 1, n) if(!r[i]) {
int x = i; q[x] = 1;
b[++ b0] = 0;
do {
b[b0] ++;
x = a[x];
q[x] = 1;
} while(x != 0);
}
fo(i, 1, n) if(!q[i]) {
int x = i, len = 0;
do {
len ++;
x = a[x];
q[x] = 1;
} while(x != i);
cnt[len] ++;
}
sum = 1;
fo(i, 1, n) sum = sum * f[i][cnt[i]] % mo, s2 += cnt[i] * (i > 2);
dg(1);
pp("%lld", ans);
}
CF 398 E(动态规划)的更多相关文章
- CF 848E(动态规划+分治NTT)
传送门: http://codeforces.com/problemset/problem/848/E 题解: 假设0-n一定有一条边,我们得到了一个方案,那么显然是可以旋转得到其他方案的. 记最大的 ...
- 四角递推(CF Working out,动态规划递推)
题目:假如有A,B两个人,在一个m*n的矩阵,然后A在(1,1),B在(m,1),A要走到(m,n),B要走到(1,n),两人走的过程中可以捡起格子上的数字,而且两人速度不一样,可以同时到一个点(哪怕 ...
- CF 1096D Easy Problem [动态规划]
题目链接:http://codeforces.com/problemset/problem/1096/D 题意: 有一长度为n的字符串,每一字符都有一个权值,要求现在从中取出若干个字符,使得字符串中没 ...
- CF思维联系–CodeForces - 225C. Barcode(二路动态规划)
ACM思维题训练集合 Desciption You've got an n × m pixel picture. Each pixel can be white or black. Your task ...
- CF 494 F. Abbreviation(动态规划)
题目链接:[http://codeforces.com/contest/1003/problem/F] 题意:给出一个n字符串,这些字符串按顺序组成一个文本,字符串之间用空格隔开,文本的大小是字母+空 ...
- CF 414B Mashmokh and ACM 动态规划
题意: 给你两个数n和k.求满足以下条件的数列有多少个. 这个数列的长度是k: b[1], b[2], ……, b[k]. 并且 b[1] <= b[2] <= …… <= b[k] ...
- CF思维联系– Codeforces-987C - Three displays ( 动态规划)
ACM思维题训练集合 It is the middle of 2018 and Maria Stepanovna, who lives outside Krasnokamensk (a town in ...
- 【DP专辑】ACM动态规划总结
转载请注明出处,谢谢. http://blog.csdn.net/cc_again?viewmode=list ---------- Accagain 2014年5月15日 ...
- 【CF932G】Palindrome Partition(回文树,动态规划)
[CF932G]Palindrome Partition(回文树,动态规划) 题面 CF 翻译: 给定一个串,把串分为偶数段 假设分为了\(s1,s2,s3....sk\) 求,满足\(s_1=s_k ...
随机推荐
- 热修复框架Tinker的从0到集成之路(转)
转自:http://blog.csdn.net/lisdye2/article/details/54411727 热修复框架Tinker的从0到集成之路 转载请标明出处: http://blog.cs ...
- 使用appium1.4在android8.0真机上测试程序时报错command failed shell "ps 'uiautomator'"的解决方式
appium1.4,运行自动化脚本时提示 org.openqa.selenium.SessionNotCreatedException: A new session could not be crea ...
- Linux part2(系统的相关设置变更)
修改Linux的系统语言 首先查看当前系统的语言 1.echo $LANG 查看当前操作系统的语言 中文:zh_CN.UTF-8 英文: en_US.UTF-8 2.临时更改默认语言,当前立即生效 重 ...
- spring 新建mybatis ...
一. 创建bean类 package com.feilong.blog.dao; public class Message { private int id; private String autho ...
- spark算子之Aggregate
Aggregate函数 一.源码定义 /** * Aggregate the elements of each partition, and then the results for all the ...
- Spring boot自定义拦截器和拦截器重定向配置简单介绍
大家好: 本文简单介绍一下用于权限控制的Spring boot拦截器配置,拦截器重定向问题. 开发工具:jdk1.8 idea2017(付费版,网上找的破解教程) 1,首先使用idea创建一个Sp ...
- SQL 在表中插入
SQL INSERT INTO 语句(在表中插入) INSERT INTO 语句用于向表中插入新记录. SQL INSERT INTO 语句 INSERT INTO 语句用于向表中插入新记录. SQL ...
- Windows注册表的学习
什么是注册表 注册表是Windows在Win95/98系统开始引入的一种核心数据库,里面存放着各类的配置信息.参数等.直接控制着系统的启动.硬件的装载以及Winodws程序的运行 手册表的功能 记录用 ...
- 【Java架构:基础技术】一篇文章搞掂:Spring Tool Suite(STS)
1.简介 STS,是一个自定义版本的Eclipse,她可以方便地用来与各种Spring项目进行交互协作,建议采用Spring进行开发的时候,可以尝试使用这个IDE 2.下载与安装 登录https:// ...
- 兼容软件,Wine安装,Crossover安装,
EL6 (RHEL6 and SL6) Required packages for proper building of 32-bit Wine on 64-bit EL6 yum install - ...