题解 「2017 山东一轮集训 Day7」逆序对
Description
给定 $ n, k $,请求出长度为 $ n $ 的逆序对数恰好为 $ k $ 的排列的个数。答案对 $ 10 ^ 9 + 7 $ 取模。
对于一个长度为 $ n $ 的排列 $ p $,其逆序对数即满足 $ i < j $ 且 $ p_i > p_j $ 的二元组 $ (i, j) $ 的数量。
一行两个整数 $ n, k $。
一行,表示答案。
对于 $ 20% $ 的数据,$ n, k \leq 20 $;
对于 $ 40% $ 的数据,$ n, k \leq 100 $;
对于 $ 60% $ 的数据,$ n, k \leq 5000 $;
对于 $ 100% $ 的数据,$ 1 \leq n, k \leq 100000, 1 \leq k \leq \binom{n}{2} $。
Solution
可以想到,对于一个排列 \(p\) ,假设 \(s_i\) 表示以 \(i\) 为右端点的逆序对个数,那么可以看出一个 \(s_{1,2,...,n}\) 对应一个唯一的 \(p\) ,而一个 \(s_{1,2,...,n}\) 合法当且仅当 \(\forall i,s_i\le i-1\)。
可以想到我们可以容斥,即枚举哪些点 \(s_i\) 越界了。那么,我们也就只需要求出
\]
的前面 \(k\) 项。
这个时候我们就有两种办法,一种是用多项式,取 \(\ln\) ,然后用 \(\ln(1-x)=\sum_{j=1}^{\infty} -\frac{x^j}{j}\) \(\Theta(k\log k)\) 直接多项式 \(\ln,\exp\) 算出来,考场上我就写的这个,不过原题要写任意模数 NTT,估计不是很好写,而且常数很大,可以拿头过。
还有另外一种 \(\Theta(k\sqrt k)\) 做法。你发现选出一个 \(\{1,2,...,n\}\) 的集合还有另外一种选法,即假设你现在有一个递减序列,你每次有两种选择:
整体加 \(1\)
整体加 \(1\) 并在后面增加一个 \(1\)
那么,我们就可以进行 dp 了,因为考虑到我们最多使用 \(\sqrt k\) 次操作 \(2\),所以,我们可以设 \(f_{i,j}\) 表示在经过 \(i\) 此操作 \(2\) 后数字总和为 \(j\) 的方案数。
可以得到转移式:
\]
Code
#include <bits/stdc++.h>
using namespace std;
#define Int register int
#define mod 1000000007
#define MAXN 200005
template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
template <typename T> inline void chkmax (T &a,T b){a = max (a,b);}
int n,k,upp = 2e5,fac[MAXN],ifac[MAXN],f[505][MAXN];
int mul (int a,int b){return 1ll * a * b % mod;}
int dec (int a,int b){return a >= b ? a - b : a + mod - b;}
int add (int a,int b){return a + b >= mod ? a + b - mod : a + b;}
int qkpow (int a,int b){
int res = 1;for (;b;b >>= 1,a = mul (a,a)) if (b & 1) res = mul (res,a);
return res;
}
void Sub (int &a,int b){a = dec (a,b);}
void Add (int &a,int b){a = add (a,b);}
int binom (int a,int b){return a >= b ? mul (fac[a],mul (ifac[b],ifac[a - b])) : 0;}
int F[MAXN];
signed main(){
read (n,k);int up = 500;
fac[0] = 1;for (Int i = 1;i <= upp;++ i) fac[i] = mul (fac[i - 1],i);
ifac[upp] = qkpow (fac[upp],mod - 2);for (Int i = upp;i;-- i) ifac[i - 1] = mul (ifac[i],i);
f[0][0] = 1;
for (Int i = 1;i <= up;++ i)
for (Int j = 0;j <= k;++ j){
if (j >= i) Add (f[i][j],add (f[i][j - i],f[i - 1][j - i]));
if (j >= n + 1) Sub (f[i][j],f[i - 1][j - n - 1]);
}
for (Int S = 0;S <= k;++ S)
for (Int i = 0;i <= up;++ i)
if (i & 1) Sub (F[S],f[i][S]);
else Add (F[S],f[i][S]);
int ans = 0;
for (Int S = 0;S <= k;++ S) Add (ans,mul (F[S],binom (k - S + n - 1,n - 1)));
write (ans),putchar ('\n');
return 0;
}
题解 「2017 山东一轮集训 Day7」逆序对的更多相关文章
- 【LOJ6077】「2017 山东一轮集训 Day7」逆序对 生成函数+组合数+DP
[LOJ6077]「2017 山东一轮集训 Day7」逆序对 题目描述 给定 n,k ,请求出长度为 n的逆序对数恰好为 k 的排列的个数.答案对 109+7 取模. 对于一个长度为 n 的排列 p ...
- loj #6077. 「2017 山东一轮集训 Day7」逆序对
#6077. 「2017 山东一轮集训 Day7」逆序对 题目描述 给定 n,k n, kn,k,请求出长度为 n nn 的逆序对数恰好为 k kk 的排列的个数.答案对 109+7 10 ^ 9 ...
- 「2017 山东一轮集训 Day7」逆序对
题解: 满满的套路题.. 首先显然从大到小枚举 然后每次生成的逆序对是1----(i-1)的 这样做dp是nk的 复杂度太高了 那我们转化一下问题 变成sigma(ai (ai<i) )= ...
- LOJ6077「2017 山东一轮集训 Day7」逆序对 (生成函数+多项式exp?朴素DP!)
题面 给定 n , k n,k n,k ,求长度为 n n n 逆序对个数为 k k k 的排列个数,对 1 e 9 + 7 \rm1e9+7 1e9+7 取模. 1 ≤ n , k ≤ 100 ...
- loj6077. 「2017 山东一轮集训 Day7」逆序对
题目描述: loj 题解: 容斥+生成函数. 考虑加入的第$i$个元素对结果的贡献是$[0,i-1]$,我们可以列出生成函数. 长这样:$(1)*(1+x)*(1+x+x^2)*--*(1+x+x^2 ...
- LOJ #6119. 「2017 山东二轮集训 Day7」国王
Description 在某个神奇的大陆上,有一个国家,这片大陆的所有城市间的道路网可以看做是一棵树,每个城市要么是工业城市,要么是农业城市,这个国家的人认为一条路径是 exciting 的,当且仅当 ...
- loj6119 「2017 山东二轮集训 Day7」国王
题目描述 在某个神奇的大陆上,有一个国家,这片大陆的所有城市间的道路网可以看做是一棵树,每个城市要么是工业城市,要么是农业城市,这个国家的人认为一条路径是 exciting 的,当且仅当这条路径上的工 ...
- loj #6079. 「2017 山东一轮集训 Day7」养猫【最大费用最大流】
首先假设全睡觉,然后用费用流考虑平衡要求建立网络流 把1~n的点看作是i-k+1~k这一段的和,连接(i,i+k,1,e[i]-s[i]),表示把i改成吃饭,能对i~i+k-1这一段的点产生影响:然后 ...
- LOJ6079「2017 山东一轮集训 Day7」养猫
养ImmortalCO k可重区间问题 的增强版:有上下界! 直接都选择s[i],然后再把一些调整到e[i] 考虑通过最大流的“最大”,使得至少每k个有me个e, 通过最大流的“上界”,限制每k个最多 ...
随机推荐
- CentOS_Server with GUI入门
安装模式: Server with GUI:基本的桌面系统,包括常用的桌面软件,如文档查看工具 Minimal:基本的系统,不含有任何可选的软件包 Basic Server :安装的基本系统的平台支持 ...
- vue3.0入门(三)
前言 最近在b站上学习了飞哥的vue教程 学习案例已上传,下载地址 class绑定 对象绑定 :class='{active:isActive}' // 相当于class="active&q ...
- 从零开始实现简单 RPC 框架 7:网络通信之自定义协议(粘包拆包、编解码)
当 RPC 框架使用 Netty 通信时,实际上是将数据转化成 ByteBuf 的方式进行传输. 那如何转化呢?可不可以把 请求参数 或者 响应结果 直接无脑序列化成 byte 数组发出去? 答:直接 ...
- 前后端数据交互(四)——fetch 请求详解
fetch 是 XMLHttpRequest 的升级版,使用js脚本发出网络请求,但是与 XMLHttpRequest 不同的是,fetch 方式使用 Promise,相比 XMLHttpReques ...
- 聚类算法与K-means实现
聚类算法与K-means实现 一.聚类算法的数学描述: 区别于监督学习的算法(回归,分类,预测等),无监督学习就是指训练样本的 label 未知,只能通过对无标记的训练样本的学习来揭示数据的内在规律和 ...
- Python习题集(八)
每天一习题,提升Python不是问题!!有更简洁的写法请评论告知我! https://www.cnblogs.com/poloyy/category/1676599.html 题目 要求:判断数组元素 ...
- 异步处理方式之信号(一):基础知识和signal函数说明
文章目录 1. 引言 2. 信号的概念 2.1 信号操作之忽略信号 2.2 信号操作之捕捉信号 2.3 信号操作之执行系统默认操作 2.4 常见的信号 3. 函数signal 3.1 signal函数 ...
- Python - poetry(4)管理环境
环境隔离 poetry 核心之一:使项目环境隔离,意味着始终和本地全局 Python 环境隔离 poetry 首先会检查当前项目是否在虚拟环境中运行:如果是将直接使用它,而不创建新的:如果不是,poe ...
- io流-缓冲流
单独去数据时,数据按块读入缓冲区,其后的操作则直接访问缓冲区 但是用 BufferedInputStream读取字节文件时,
- 为什么要设置GOROOT/GOPATH
设置GOROOT的原因 编译器的位置指定的时候,需要指定GO开发包的安装位置,然后设置环境变量PATH的时候,需要指定到安装包下的bin目录,其中就有以下的编译/执行器.所以GOROOT指定了前面的路 ...