CF1542E2 Abnormal Permutation Pairs (hard version)

good tea。

对于两个排列 \(p,q\),如果 \(p\) 的字典序小于 \(q\),则要么 \(p_1<q_1\),要么存在一个 \(i\) 使得 \(p_{1\sim i}=q_{1\sim i}\) 且 \(p_{i+1}<q_{i+1}\),而后者可以转化为长度为 \(n-i\) 的排列 \(p',q'\) 满足 \(p'_1<q'_1\) 的方案数乘上 \(n^{\underline{i}}\)。因此,我们只需要对于每个 \(i\in[1,n]\) 计算长度为 \(i\) 的排列 \(p,q\) 满足 \(p_1<q_1\) 且 \(p\) 的逆序对个数大于 \(q\) 的方案数。

首先,我们可以枚举 \(p_1\) 和 \(q_1\),这样可以消除字典序的限制。它们对逆序对的贡献就分别为 \(p_1-1\) 和 \(q_1-1\)。如果再枚举 \(q_{2\sim n}\) 的逆序对个数 \(y\),那么符合限制的 \(p_{2\sim n}\) 的逆序对个数 \(x\) 应该满足 \(x+p_1-1>y+q_1-1\)。即 \(x>y+q_1-p_1\)。

根据上面的要求,我们设计 DP:设 \(f_{i,j}\) 为长度为 \(i\),逆序对数量为 \(j\) 的排列个数。转移方程很简单,因为从 \(i-1\to i\) 时只需要考虑 \(i\) 放在哪里:如果它放在倒数第 \(k\) 位,那么它对逆序对个数的贡献就是 \(k-1\)。因此转移方程为 \(f_{i,j}=\sum_{k=\max(0,j-i+1)}^jf_{i-1,k}\),显然可以前缀和优化到 \(n^3\)。

求出 \(f\) 后可以计算答案长度为排列长度为 \(n\) 时的答案了:记 \(s_{i,j}=\sum_{k=1}^j f_{i,k}\),\(m=\binom{n-1}{2}\),则答案为 \(\sum_{p_1=1}^{n-1}\sum_{q_1=p_1+1}^n\sum_{y=0}^{m-(q_1-p_1)}f_{n,y}\times(s_{n,m}-s_{n,y+q_1-p_1})\)。该部分时间复杂度为 \(n^4\),则总时间复杂度 \(n^5\),显然无法承受。

注意到我们不关系 \(p_1,q_1\) 的具体值,只关心 \(q_1-p_1\),因此可以枚举 \(d=q_1-p_1\),那么使 \(q_1-p_1=d\) 的 \(q_1,p_1\) 一共有 \(n-d\) 种情况。上述柿子变为 \(\sum_{d=1}^{n-1}\sum_{y=0}^{m-d}f_{n,y}\times (s_{n,m}-s_{n,y+d})\times (n-d)\)。总时间复杂度为 \(n^4\),还是无法承受。

那么继续拆柿子!此时我们只枚举 \(y\) 对于特定的 \(y\),\(f_{n,y}s_{n,m}(n-d)\) 显然可以把与 \(d\) 无关的 \(f_{n,y}s_{n,m}\) 用乘法分配律提出,那么因为 \(d\) 的上界为 \(t=\min(i-1,m-y)\),所以 \(\sum_{d=1}^t(n-d)\) 显然可以用等差数列求和公式快速求出,即为 \(\frac{(2n-1-t)t}{2}\)。

剩下来的 \(-f_{n,y}s_{n,y+d}(n-d)\) 似乎有些棘手。没关系,先把与 \(d\) 无关的 \(-f_{n,y}\) 提出,注意到 \(s_{n,y+d}(n-d)\) 中的 \(s_{n,y+d}\) 随着 \(d\) 的递增,其前面的系数是递减的。老套路了:把 \(n-d\) 拆成 \((n+y)-(y+d)\)。\(-s_{n,y+d}(y+d)\) 显然可以前缀和 \(sk_{n,j}=-\sum_{k=1}^js_{n,k}\times k\) 预处理出来;\(s_{n,y+d}(n-y)\) 把 \(n-y\) 提出来,预处理 \(s\) 的前缀和即可。

时间复杂度 \(n^3\)。代码中 \(y\) 的枚举上界是 \(m-d-1\) 而不是 \(m-d\),因为 \(y=m-d\) 时 \(s_{n,m}-s_{n,y+d}=s_{n,m}-s_{n,m}=0\),对答案无影响。代码中的 \(r\) 即为计算 \(-f_{n,y}s_{n,y+d}(n-d)\) 时 \(y+d\) 的上界。

#include <bits/stdc++.h>
using namespace std; const int N=505; int n,mod,ans,f[N][N*N/2],s[N][N*N/2],pp[N*N/2],ss[N*N/2]; int main(){
cin>>n>>mod,f[1][0]=s[1][0]=s[1][1]=1;
for(int i=2;i<=n;i++){
for(int j=0;j<=i*(i-1)/2;j++){
f[i][j]=(s[i-1][j]-(j<i?0:s[i-1][j-i])+mod)%mod;
s[i][j]=((j?s[i][j-1]:0)+f[i][j])%mod;
} ans=1ll*ans*i%mod;
for(int j=i*(i-1)/2+1;j<=i*(i+1)/2;j++)s[i][j]=s[i][j-1];
if(i<=3)continue;
int lim=(i-1)*(i-2)/2;
for(int j=0;j<=lim;j++){
tmpp[j]=((j==0?0:tmpp[j-1])-s[i-1][j]*j%mod+mod)%mod,
tmps[j]=((j==0?0:tmps[j-1])+s[i-1][j])%mod;
}
for(int j=0;j+2<=lim;j++){
int times=min(lim-j-1,i-1),c=(i-1+i-times)*times/2,r=min(lim-1,j+i-1);
ans=(ans+1ll*f[i-1][j]%mod*s[i-1][lim]%mod*c)%mod;
ans=(ans-1ll*f[i-1][j]*(pp[r]-pp[j]+(ss[r]-ss[j])*(i+j)%mod)%mod+mod)%mod;
}
}
cout<<ans<<endl;
return 0;
}

CF1542E2 Abnormal Permutation Pairs (hard version)的更多相关文章

  1. Codeforces 1542E2 - Abnormal Permutation Pairs (hard version)(DP)

    upd on 2021.7.7:修了个 typo Codeforces 题目传送门 & 洛谷题目传送门 首先考虑怎样处理"字典序小"这个问题,按照字典序比大小的套路,我们可 ...

  2. 洛谷 P5853 - [USACO19DEC]Tree Depth P(生成函数+背包)

    洛谷题面传送门 神仙题. 首先考虑一个点的深度是什么,注意到对于笛卡尔树而言直接从序列的角度计算一个点的深度是不容易的,因为这样会牵扯到序列中多个元素,需要 fixed 的东西太多,计算起来太复杂了. ...

  3. DP 做题记录 II.

    里面会有一些数据结构优化 DP 的题目(如 XI.),以及普通 DP. *I. P3643 [APIO2016]划艇 题意简述:给出序列 \(a_i,b_i\),求出有多少序列 \(c_i\) 满足 ...

  4. LeetCode解题报告—— Swap Nodes in Pairs & Divide Two Integers & Next Permutation

    1. Swap Nodes in Pairs Given a linked list, swap every two adjacent nodes and return its head. For e ...

  5. error: checker javascript/jshint: can’t parse version string (abnormal termination?)”

    vim 安装插件(k-vim方法 )好后 编辑js文件提示错误 可能是nodejs环境没搭建好 或者版本有误 用nvm安装node 后 需要 source ~/.bashrc 或者重新开一个终端 再运 ...

  6. one recursive approach for 3, hdu 1016 (with an improved version) , permutations, N-Queens puzzle 分类: hdoj 2015-07-19 16:49 86人阅读 评论(0) 收藏

    one recursive approach to solve hdu 1016, list all permutations, solve N-Queens puzzle. reference: t ...

  7. Create side-by-side stereo pairs in the Unity game engine

    Create side-by-side stereo pairs in the Unity game engine Paul BourkeDecember 2008 Sample Island pro ...

  8. ePass1000 Full ActiveX Control Reference Manual Version 2.0

    ePass1000 Full ActiveX Control Reference Manual Version 2.0 Error Code Value Return Status Descripti ...

  9. hdu 2583 permutation

    permutation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

随机推荐

  1. javascript-jquery选择器

    jquery选择器用来获得jquery对象 我们用一个实例来演示jquery与原生的区别 <div id="title">123</div>原生获得元素的方 ...

  2. DDD领域驱动设计-概述-Ⅰ

     如果我看得更远,那是因为我站在巨人的肩膀上.(If I have seen further it is by standing on ye shoulder of Giants.)         ...

  3. [敏捷软工团队博客]Beta阶段事后分析

    设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们的软件要解决的问题是:现在的软工课程的作业分布在博客园.GitHub上,没有一个集成多种功能的一体化 ...

  4. Spring Cloud Alibaba整合Sentinel

    Spring Cloud Alibaba 整合 Sentinel 一.需求 二.实现步骤 1.下载 sentinel dashboard 2.服务提供者和消费者引入sentinel依赖 3.配置控制台 ...

  5. SDIO总线协议

    SDIO采用HOST-DEVICE模式,所有通信都由HOST端发命令,DEVICE设备只要解析HOST命令就可与HOST进行通信. SDIO总线的几根线: 1.  CLK信号:HOST给DEVICE的 ...

  6. 【做题记录】[NOIP2016 普及组] 魔法阵

    P2119 魔法阵 2016年普及组T4 题意: 给定一系列元素 \(\{X_i\}\) ,求满足以下不等式的每一个元素作为 \(a,b,c,d\) 的出现次数 . \[\begin{cases}X_ ...

  7. 你知道怎么从jar包里获取一个文件的内容吗

    目录 背景 报错的代码 原先的写法 编写测试类 找原因 最终代码 背景 项目里需要获取一个excle文件,然后对其里的内容进行修改,这个文件在jar包里,怎么尝试都读取不成功,但是觉得肯定可以做到,因 ...

  8. ST表 求 RMQ(区间最值)

    RMQ即Range Minimum/Maximun Query,中文意思:查询一个区间的最小值/最大值 比如有这样一个数组:A{3 2 4 5 6 8 1 2 9 7},然后问你若干问题: 数组A下标 ...

  9. 批量免密ssh

    参考连接:https://www.cnblogs.com/xiaoyuxixi/p/11413355.html 适用于所有密码都一样的情况下 应用场景: 在应用ansible的实际情况中,有一个很现实 ...

  10. 记一次线上环境 ES 主分片为分配故障

    故障前提 ElasticSearch 版本:5.2 集群节点数:5 索引主分片数:5 索引分片副本数:1 线上环境ES存储的数据量很大,当天由于存储故障,导致一时间 5个节点的 ES 集群,同时有两个 ...