传送门:


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);
}

转载于:https://www.cnblogs.com/coldchair/p/11143082.html

CF 398 E(动态规划)相关推荐

  1. CF思维联系–CodeForces - 225C. Barcode(二路动态规划)

    ACM思维题训练集合 Desciption You've got an n × m pixel picture. Each pixel can be white or black. Your task ...

  2. cf 414B Mashmokh and ACM 动态规划

    题目链接:http://codeforces.com/problemset/problem/414/B dp[i][j]表示长度为i.最后一个数字为j的合法序列总数 dp[1][1...2000]都是 ...

  3. CF思维联系– Codeforces-987C - Three displays ( 动态规划)

    ACM思维题训练集合 It is the middle of 2018 and Maria Stepanovna, who lives outside Krasnokamensk (a town in ...

  4. 【BZOJ5311/CF321E】贞鱼/Ciel and Gondolas(动态规划,凸优化,决策单调性)

    [BZOJ5311/CF321E]贞鱼/Ciel and Gondolas(动态规划,凸优化,决策单调性) 题面 BZOJ CF 洛谷 辣鸡BZOJ卡常数!!!!!! 辣鸡BZOJ卡常数!!!!!! ...

  5. 动态规划总结与题目分类

    源博客链接:http://blog.csdn.net/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码量少 ...

  6. 【CF809D】Hitchhiking in the Baltic States(Splay,动态规划)

    [CF809D]Hitchhiking in the Baltic States(Splay,动态规划) 题面 CF 洛谷 题解 朴素\(dp\):设\(f[i][j]\)表示当前考虑到第\(i\)个 ...

  7. 『ACM-算法-动态规划』初识DP动态规划算法

    一.多阶段决策过程的最优化问题 在现实生活中,有类活 动的过程,由于 它的特殊性,可将过程分成若干个互相阶段.在它的每一阶段都需要作出决策,从而使整个过程达到最好的活动效果.当阶段决策的选取不是任意确 ...

  8. 【CF 1188 A1,B,C】Add on a Tree // Count Pairs // Array Beauty

    传送门 这些天风也温柔,题也温柔 开车啦! 文章目录 A1:Add on a Tree 题意翻译 题解 证明 代码实现 B:Count Pairs 题意翻译 题解 代码实现 C:Array Beaut ...

  9. (转)dp动态规划分类详解

    dp动态规划分类详解 转自:http://blog.csdn.NET/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间 ...

最新文章

  1. (转)如何从storyBoard中加载其中一个controller
  2. Unity3d中角色模型和角色名字保持相对位置
  3. 如何将更改的文件添加到Git中的旧(不是最后)提交
  4. ASP.NET 会话状态
  5. php企业站数据表,php – 创建一个站点来查询表的数据库
  6. Echarts开源可视化库学习(三)主题的使用
  7. BZOJ 1008 [HNOI2008]越狱
  8. 小企业服务器设置位置,小企业服务器配置
  9. 第一个flash游戏--配对游戏
  10. Apple Mach-O Linker Error _sqlite3_exec, referenced from: _sqlite_open, referenced from: _sqlit
  11. 华为云怎么样_为什么阿里云要迁移到华为云?详细过程分析
  12. golang http长连接
  13. jquery.seat-chartsMark在线选座插件使用
  14. 推荐 干掉垃圾流氓插件得批处理文件和注册表文件
  15. vc6.0精简版支持win7 64位版本
  16. 3、MybatisPlus
  17. 如何使用ArcGIS制作真实的植被
  18. 实战案例:如何快速打造1000万+播放量的抖音网红?
  19. 木纹标识lisp_Lisp 中的 string 和 symbol 的区别?
  20. ESD防护的4种静电保护设计

热门文章

  1. java list平均分成5份_java中将一个List等分成n个list的工具方法(推荐)
  2. java编程两个超长正整数相减_【每日编程237期】数字分类
  3. linux 看rabbit版本,Linux下安装rabbitMq
  4. 又见n/i下取整+分块
  5. 电商网站模板_微购物商城网站建设:要做好这6点!
  6. leetcode 93.复原IP地址 dfs解法
  7. 蛮力法 —— 求解迷宫问题 —— DFS和BFS
  8. 递归法:汉诺塔(快速掌握)
  9. 2018 Multi-University Training Contest 4: B. Harvest of Apples(分块打表)
  10. opencv 创建调色板