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. Vue3学习(八)之 Vue CLI多环境配置

    一.前言 这里相对于之前就没那么麻烦了,通俗点说就是使用配置文件来管理多环境,实现环境的切换. 二.实现切换 1.增加开发和生产配置文件 在web的根目录下,创建开发环境切换配置文件.env.dev, ...

  2. linux centos7 修改默认网卡命名规则为eth0脚本

    CentOS6之前基于传统的命名方式如:eth1,eth0.... Centos7提供了不同的命名规则,默认是基于固件.拓扑.位置信息来分配.这样做的优点是命名是全自动的.可预知的,缺点是比eth0. ...

  3. springBoot服务整合线程池ThreadPoolTaskExecutor与@Async详解使用

    ThreadPoolExecutor:=======这个是java自己实现的线程池执行类,基本上创建线程池都是通过这个类进行的创建.ThreadPoolTaskExecutor:========这个是 ...

  4. UVA-1498 Activation

    UVA-1498 DP应该是肯定的,设 f [ i ] [ j ] 表示现在对中共有 i 人,Tomato在第 j 个,出现所求情况的概率,我们可以很(简单的)艰难的列出下列方程: f[i][1] = ...

  5. camera isp(Image Signal Processor)

    1. 目标[52RD.com] 手机摄像头模组用ISP功能模块的市场走向及研发方向.为能够正确认识手机摄像模组行业提供技术及市场依据.[52RD.com] 2. ISP在模组上的应用原理[52RD.c ...

  6. DP接口中AUX

    背景技术: DP接口(DisplayPort)是一种图像显示接口,它不仅可以支持全高清显示分辨率(1920×1080),还能支持4k分辨率(3840×2160),以及最新的8k分辨率(7680×432 ...

  7. 替换空格 牛客网 剑指Offer

    替换空格 牛客网 剑指Offer 题目描述 请实现一个函数,将一个字符串中的每个空格替换成"%20".例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20A ...

  8. 记录一次因subprocess PIPE 引起的线上故障

    sence:python中使用subprocess.Popen(cmd, stdout=sys.STDOUT, stderr=sys.STDERR, shell=True) ,stdout, stde ...

  9. Latex使用CJK包添加字体

    最近写论文时有个中文期刊提供的LaTeX模板使用CJK宏包,大致是这样的: \documentclass{article} \usepackage{CJK} \begin{document} \beg ...

  10. Linux内核内存检测工具KASAN

    KASAN 是 Kernel Address Sanitizer 的缩写,它是一个动态检测内存错误的工具,主要功能是检查内存越界访问和使用已释放的内存等问题.KASAN 集成在 Linux 内核中,随 ...