DTOJ 4896. 地斗王

题意

在没有受疫情影响的另一个世界中,小 U 和 CZL 都已经开学了。一天,小 U, CZL 和 ZYC 在寝 室里面玩扑克牌。

CZL 有一副奇怪的扑克牌,包含了 n n n 张扑克牌。牌堆从上到下有一个编号,从上到下第 i i i 张牌的 编号为 a i a_i ai。其中不同的牌的编号可能相同。现在, CZL 把这副牌重新排列,使得从上到下第 i i i 张牌的 编号变为 a i ′ a_ i ' ai。然后, CZL 把这副打乱过的牌给小 U 来排序,即:使牌堆从上到下的编号不降。小 U 只 能交换相邻两张牌的位置。他会选择一个所用的操作次数最少的方法给这副牌排序。接着, CZL 把这副 牌复原成 a 1 ′ , ⋯   , a n ′ a_1',\cdots ,a_n' a1,,an 后,给 ZYC 排序。 ZYC 可以交换任意两张牌的位置,他也会选择一个所用操作次数最少的方法给这副牌排序。如果小 U 和 ZYC 所用的最少操作次数相等,那么就称 a 1 ′ , ⋯   , a n ′ a_1',\cdots, a_n' a1,,an 是好的 牌堆。

现在小 U 想要知道在可能生成的牌堆中,有多少种好的牌堆。由于答案很大,你只需要输出答案模 1000000007 1000000007 1000000007 的余数 。

对于所有数据, 1 ≤ n ≤ 1 0 6 , 1 ≤ a i ≤ 1 0 9 1 \le n \le 10^6 ,1 \le ai \le 10^9 1n106,1ai109

task1( 15pts) : n ≤ 8 n \le 8 n8

task2( 18pts) : n ≤ 15 n \le 15 n15

task3(13pts) : a 1 = 1 , a 2 = 2 , ⋯   , a n = n a_1=1,a_2=2,\cdots,a_n=n a1=1,a2=2,,an=n

task4(19pts) : 1 ≤ a 1 , ⋯   , a n ≤ 8 1 \le a_1,\cdots,a_n \le 8 1a1,,an8

task5(35pts) : 无特殊条件

题解

原本只推出了第三个子任务,即排列的情况:首先交换相邻两张牌的位置的最小值是排列逆序对个数,而交换任意两张牌的位置的最小值是n-把每个数连向对应位置后形成的环的个数。注意到每个环至少贡献环长-1的逆序对数,且恰好贡献环长-1的逆序对数,当且仅当从最左端一直向右连向最右端,再向左连回来依次补全空缺。且如果环之间相交,那么一定会产生不在同一个环上的逆序对,这样逆序对个数就大于n-环数了。故合法的方案一定是把整个排列分为若干段,每段分别是一个上述合法的环,DP计数即可(原本写了个直接DP是 O ( n 2 ) O(n^2) O(n2)的,然后喜提0分,需要前缀和优化成 O ( n ) O(n) O(n))。

考虑有相等的数该怎么办,此时每个数连向的位置不是确定的,而是一段区间中的任意一个数,且相等的那些数要恰好连完对应的位置。交换相邻两张牌的位置的最小值仍是逆序对个数,而交换任意两张牌的位置的最小值是n-所有的连边方案的最大环数。发现一个环中若有相同的元素难以计数,又发现此时一定可以把这个环拆成两个环,所以这种情况直接不考虑即可。这样,前面的结论仍是正确的,在DP时,我们把a升序排序,分为若干段每段没有相同数字的段,也是直接DP+前缀和优化即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值