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)的更多相关文章
- Codeforces 1542E2 - Abnormal Permutation Pairs (hard version)(DP)
upd on 2021.7.7:修了个 typo Codeforces 题目传送门 & 洛谷题目传送门 首先考虑怎样处理"字典序小"这个问题,按照字典序比大小的套路,我们可 ...
- 洛谷 P5853 - [USACO19DEC]Tree Depth P(生成函数+背包)
洛谷题面传送门 神仙题. 首先考虑一个点的深度是什么,注意到对于笛卡尔树而言直接从序列的角度计算一个点的深度是不容易的,因为这样会牵扯到序列中多个元素,需要 fixed 的东西太多,计算起来太复杂了. ...
- DP 做题记录 II.
里面会有一些数据结构优化 DP 的题目(如 XI.),以及普通 DP. *I. P3643 [APIO2016]划艇 题意简述:给出序列 \(a_i,b_i\),求出有多少序列 \(c_i\) 满足 ...
- 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 ...
- error: checker javascript/jshint: can’t parse version string (abnormal termination?)”
vim 安装插件(k-vim方法 )好后 编辑js文件提示错误 可能是nodejs环境没搭建好 或者版本有误 用nvm安装node 后 需要 source ~/.bashrc 或者重新开一个终端 再运 ...
- 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 ...
- 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 ...
- ePass1000 Full ActiveX Control Reference Manual Version 2.0
ePass1000 Full ActiveX Control Reference Manual Version 2.0 Error Code Value Return Status Descripti ...
- hdu 2583 permutation
permutation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
随机推荐
- Golang通脉之面向对象
面向对象的三大特征: 封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式 继承:使得子类具有父类的属性和方法或者重新定义.追加属性和方法等 多态:不同对象中同种行为的不同实现方式 Go并不是一个纯 ...
- Hadoop面试题(四)——YARN
1.简述hadoop1与hadoop2 的架构异同 1)加入了yarn解决了资源调度的问题. 2)加入了对zookeeper的支持实现比较可靠的高可用. 2.为什么会产生 yarn,它解决了什么问题, ...
- js--Symbol 符号基本数据类型
前言 ECMAScript 6 中新增了 Symbol 符号这一基本数据类型,那么Symbol 是用来干什么的,对开发又有什么帮助呢?本文来总结记录一下 Symbol 的相关知识点. 正文 Symbo ...
- Sequence Model-week2编程题2-Emoji表情生成器
1. Emoji表情生成器 下面,我们要使用词向量(word vector)来构建一个表情生成器. 你将实现一个模型:输入一句话 (如 "Let's go see the baseball ...
- Alpha阶段初始任务分配
项目 内容 这个作业属于哪个课程 2021春季软件工程(罗杰 任健) 这个作业的要求在哪里 团队项目-计划-Alpha阶段说明书 一.Alpha阶段总体规划 进行服务器相关部署 进行开发相关技术学习 ...
- Pandas核心用法
目录 Numpy和Pandas Numpy科学计算 Pandas数据分析 安装jupyter notebook Numpy语法 创建和基本使用 切片索引 布尔索引 对位运算 矩阵的乘除 其他方法 Pa ...
- 利用Nginx搭建Ambari本地安装源
1.下载本地源包https://docs.hortonworks.com/HDPDocuments/Ambari-2.7.3.0/bk_ambari-installation/content/ch_o ...
- python3+Robotframework+ride+Selenium2Library+Autoitlibrary环境搭建
1.安装python3.8 第一步是安装Python:https://www.python.org/,RF框架是基于python 的,所以一定要有python环境.将python-3.8.2-amd6 ...
- Python Excel工具类封装, 给excel表头搞点颜色
封装Excel工具类 我们常用的excel工具类,读有xlrd,写有xlwt.有读有写,新一代库有pandas,openpyxl等等. 大家用法都差不多,今天博主就介绍新手最爱,我也爱的xlrd和xl ...
- BootStrap_1 浓缩版本
BootStrap(基于JQuery框架) 商业互吹:Bootstrap是最受欢迎的HTML.CSS和JS框架,用于开发响应式布局,移动设备优先选择的WEB项目... 特色:1.响应式布局 2.基于f ...