LOJ - 6077 逆序对
时间:2021-08-09
本文章向大家介绍LOJ - 6077 逆序对,主要包括LOJ - 6077 逆序对使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目
解法
\(\text{40 pts}\)
从小到大放置 \(n\) 个数,对于第 \(i\) 个数就有 \(i\) 个位置放置,贡献值域为 \([0,i-1]\)。
令 \(dp_{i,j}\) 为前 \(i\) 个数形成 \(j\) 个逆序对的方案数。就有:
\[dp_{i,j}=\sum_{k=0}^{i-1} dp_{i-1,j-k}
\]
\(\text{60 pts}\)
\[dp_{i,j}-dp_{i,j-1}=dp_{i-1,j}-dp_{i-1,j-i}
\]
\(\text{100 pts}\)
问题可以转换成这样的形式:求满足
\[\sum_{i=1}^n x_i=k,x_i\le i-1
\]
的解的方案数。
可以钦定 \(m\) 个 \(x_i\) 不满足性质,设这些 \(x_i\) 的 \(i\) 之和为 \(s\)(\(x_i\) 值为 \(i\) 恰好不满足性质)。那么方案数就是 \(\binom{n-1}{k+n-1-s}\),容斥系数是 \((-1)^m\)。
这显然过不去,但其实我们并不关心是哪些 \(x_i\) 超过限制,我们关心的是 \(s\) 和 \(m\)。
那么令 \(dp_{i,j}\) 为选 \(i\) 个数,它们的和为 \(j\) 的方案数。由于这 \(i\) 个数 互异,可以这样转移:
- 将所选数整体 \(+1\)。\(dp_{i,j}=dp_{i,j-i}\)。
- 将所选数整体 \(+1\),再加入一个值为 \(1\) 的数。\(dp_{i,j}=dp_{i,j}+dp_{i-1,j-i}\)。
- 有数字加出了 \(n\),需要减去。\(dp_{i,j}=dp_{i,j}-dp_{i-1,j-(n+1)}\)。
现在就是 \(\mathcal O(n^2)\) 的咯?实际上,由于 \(k\) 的限制,我们并不需要选这么多数。考虑最节省的情况就是连续的等差数列,设项数为 \(x\):
\[\frac{(1+x)\cdot x}{2}=k
\]
这样 \(x\) 大概是 \(\sqrt k\) 级别的。总复杂度 \(\mathcal O(n\sqrt n)\)。
代码
#include <cstdio>
#define print(x,y) write(x),putchar(y)
template <class T>
inline T read(const T sample) {
T x=0; char s; bool f=0;
while((s=getchar())>'9' or s<'0')
f|=(s=='-');
while(s>='0' and s<='9')
x=(x<<1)+(x<<3)+(s^48),
s=getchar();
return f?-x:x;
}
template <class T>
inline void write(const T x) {
if(x<0) {
putchar('-'),write(-x);
return;
}
if(x>9) write(x/10);
putchar(x%10^48);
}
#include <cmath>
const int mod=1e9+7,maxn=1e5+5;
int n,k,fac[maxn<<1],ifac[maxn<<1];
int dp[600][maxn];
int qkpow(int x,int y) {
int r=1;
while(y) {
if(y&1) r=1ll*r*x%mod;
x=1ll*x*x%mod; y>>=1;
}
return r;
}
void init() {
fac[0]=1;
for(int i=1;i<=n+k;++i)
fac[i]=1ll*fac[i-1]*i%mod;
ifac[n+k]=qkpow(fac[n+k],mod-2);
for(int i=n+k-1;i>=0;--i)
ifac[i]=1ll*ifac[i+1]*(i+1)%mod;
}
int C(int n,int m) {
if(n<m or n<0 or m<0)
return 0;
return 1ll*fac[n]*ifac[m]%mod*ifac[n-m]%mod;
}
int main() {
n=read(9),k=read(9); init();
int m=sqrt(k*2)+5;
dp[0][0]=1;
for(int i=1;i<=m;++i)
for(int j=i;j<=k;++j) {
dp[i][j]=(dp[i][j-i]+dp[i-1][j-i])%mod;
if(j>=n+1)
dp[i][j]=(dp[i][j]-dp[i-1][j-(n+1)]+mod)%mod;
}
int ans=C(n+k-1,n-1);
for(int i=1;i<=k;++i) {
int tmp=0;
for(int j=1;j<=m and j<=n;++j)
if(j&1) tmp=(tmp-dp[j][i]+mod)%mod;
else tmp=(tmp+dp[j][i])%mod;
ans=(ans+1ll*C(k+n-1-i,n-1)*tmp%mod)%mod;
}
print(ans,'\n');
return 0;
}
原文地址:https://www.cnblogs.com/AWhiteWall/p/15120493.html
- Redis密码设置与访问限制(网络安全)
- Elasticsearch-sql 用SQL查询Elasticsearch
- python使用装饰器@函数式化django开发
- python 设计模式,“多”例模式
- 怎样把微信聊天记录导出备份到电脑【微信公众平台技巧】
- zookeeper curator选主(Leader)
- zookeeper curator使用caches实现各种监听
- python apschedule安装使用与源码分析
- 数据迁移过程中hive sql调优
- 词序:神经网络能按正确的顺序排列单词吗?
- 使用spark对hive表中的多列数据判重
- 如何从微信公众平台上下载关注用户(备份微信关注用户)
- 使用hive客户端java api读写hive集群上的信息
- 大数据算法设计模式(1) - topN spark实现
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- java字符串操作:如何实现字符串的反转及替换?
- 树莓派基础实验10:干簧管传感器实验
- Java 字节流 字符流 io流
- 写一个函数,要求输入一个字符串和一个字符长度,对该字符串进行分 隔。
- 树莓派基础实验11:U型光电传感器实验
- java 缓冲流+原理图解
- 写一个函数,2 个参数,1 个字符串,1 个字节数,返回截取的字符串,要 求字符串中的中文不能出现乱码
- Java 编程,打印昨天的当前时刻.
- git merge后 丢失文件 以及 代码
- 树莓派基础实验12:PCF8591模数转换器实验
- spring boot多数据源的代码实现
- 树莓派基础实验13:雨滴探测传感器实验
- Java中的TCP通信程序
- Java实现一个简单的文件上传案例
- 树莓派基础实验14:PS2操纵杆实验