[HAOI2009]逆序对数列(加强)
暴力就是 \(\Theta(n\times m)\)
如果 \(n,m \le 10^5\) ?
考虑问题的转换,设 \(a_i\) 表示 \(i\) 小的在它后面的数的个数
\(0\le a_i \le i-1\),显然任何一个满足要求的 \(a\) 数列都可以从大到小放数字构成一个满足要求的排列
那么就是要求 \(0\le a_i \le i-1,\sum_{i=1}^{n}a_i=m\) 的方案数
考虑生成函数
\]
\]
方法一
求 \(Ln\) 后,即
\]
而
\]
证明:
\]
\]
\]
\]
\]
\]
证毕
以调和级数的复杂度 \(\Theta(nlnn)\)求出来后 \(exp\) 就好了
方法二
\]
\]
后面的
\]
即就是从 \(n\) 个不同的集合中间可以重复的取出 \(i\) 个的方案数的生成函数
那么就是
\]
考虑前面的
\]
相当于一个带符号的背包计数问题
而第 \(i\) 个的体积是 \(i\)
经典 \(DP\),就是选出一个上升的序列的方案数
设 \(f[i][j]\) 表示选了 \(i\) 个,和为 \(j\) 的方案
\(f[i][j]=f[i][j-i]-f[i-1][j-i]\) (带符号)
考虑到可能有某个的大小超过 \(n\)
那么 \(f[i][j]+=f[i-1][j-(n+1)]\)
由于每个体积不同,所以最多选出 \(\sqrt{n}\) 个
复杂度 \(\Theta(n\sqrt{n})\)
#include <bits/stdc++.h>
using namespace std;
namespace IO {
const int maxn((1 << 21) + 1);
char ibuf[maxn], *iS, *iT, c;
int f;
char Getc() {
return (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, maxn, stdin), (iS == iT ? EOF : *iS++)) : *iS++);
}
template <class Int> void In(Int &x) {
for (f = 1, c = Getc(); c < '0' || c > '9'; c = Getc()) f = c == '-' ? -1 : 1;
for (x = 0; c <= '9' && c >= '0'; c = Getc()) x = (x << 3) + (x << 1) + (c ^ 48);
x *= f;
}
}
using IO :: In;
const int mod(998244353);
const int maxn(2e5 + 5);
int fac[maxn], ifac[maxn], inv[maxn], n, m, f[500][maxn];
inline void Inc(int &x, int y) {
x += y;
if (x >= mod) x -= mod;
}
inline int C(int x, int y) {
if (y > x) return 0;
return 1LL * fac[x] * ifac[y] % mod * ifac[x - y] % mod;
}
int main() {
fac[0] = fac[1] = ifac[0] = ifac[1] = inv[1] = 1;
for (int i = 2; i <= 200000; ++i) {
inv[i] = 1LL * (mod - mod / i) * inv[mod % i] % mod;
fac[i] = 1LL * fac[i - 1] * i % mod;
ifac[i] = 1LL * ifac[i - 1] * inv[i] % mod;
}
In(n), In(m);
int sz = 500, ans = 0;
f[0][0] = 1;
for (int i = 1; i < sz; ++i)
for (int j = 0; j <= m; ++j) {
if (j >= i) f[i][j] = (f[i][j - i] - f[i - 1][j - i] + mod) % mod;
if (j >= n + 1) Inc(f[i][j], f[i - 1][j - n - 1]);
}
for (int i = 0; i <= m; ++i) {
int ret = 0;
for (int j = 0; j < sz; ++j) Inc(ret, f[j][i]);
Inc(ans, 1LL * ret * C(n + m - i - 1, n - 1) % mod);
}
printf("%d\n", ans);
return 0;
}
[HAOI2009]逆序对数列(加强)的更多相关文章
- bzoj2431:[HAOI2009]逆序对数列
单组数据比51nod的那道题还弱...而且连优化都不用了.. #include<cstdio> #include<cstring> #include<cctype> ...
- BZOJ 2431: [HAOI2009]逆序对数列( dp )
dp(i,j)表示1~i的全部排列中逆序对数为j的个数. 从1~i-1的全部排列中加入i, 那么可以产生的逆序对数为0~i-1, 所以 dp(i,j) = Σ dp(i-1,k) (j-i+1 ≤ k ...
- 2431: [HAOI2009]逆序对数列
2431: [HAOI2009]逆序对数列 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 954 Solved: 548[Submit][Status ...
- P2513 [HAOI2009]逆序对数列
P2513 [HAOI2009]逆序对数列 题目描述 对于一个数列{ai},如果有iaj,那么我们称ai与aj为一对逆序对数.若对于任意一个由1~n自然数组成的数列,可以很容易求出有多少个逆序对数.那 ...
- bzoj千题计划153:bzoj2431: [HAOI2009]逆序对数列
http://www.lydsy.com/JudgeOnline/problem.php?id=2431 dp[i][j] 表示i的排列,有j个逆序对的方案数 加入i+1,此时i+1是排列中最大的数, ...
- BZOJ2431 HAOI2009 逆序对数列 【DP】*
BZOJ2431 HAOI2009 逆序对数列 Description 对于一个数列ai{a_i}ai,如果有i<j且ai>aja_i>a_jai>aj,那么我们称aia ...
- 洛谷P2513 [HAOI2009]逆序对数列
P2513 [HAOI2009]逆序对数列 题目描述 对于一个数列{ai},如果有i<j且ai>aj,那么我们称ai与aj为一对逆序对数.若对于任意一个由1~n自然数组成的数列,可以很容易 ...
- bzoj2431: [HAOI2009]逆序对数列(前缀和优化dp)
2431: [HAOI2009]逆序对数列 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 2312 Solved: 1330[Submit][Stat ...
- Bzoj 2431 HAOI2009 逆序对数列
Description 对于一个数列{ai},如果有i**<**j且ai>aj,那么我们称ai与aj为一对逆序对数.若对于任意一个由1~n自然数组成的数列,可以很容易求出有多少个逆序对数. ...
- [HAOI2009]逆序对数列
题目描述 对于一个数列{ai},如果有i<j且ai>aj,那么我们称ai与aj为一对逆序对数.若对于任意一个由1~n自然数组成的数列,可以很容易求出有多少个逆序对数.那么逆序对数为k的这样 ...
随机推荐
- Linux C 重定向简单范例
//前言:我们知道printf()会将信息输出到stdout流,然后展示到屏幕上. //那么我们所实现的简单的重定向就可以将stdout指向一个文件,然后读写,这样就达到了重定向的目的. //code ...
- iOS -- UILabel的常见使用
UILabel是iOS开发经常用到的一个控件,主要用于显示文字.下面记录一些常用的UIlabel的使用. 先定义:UILabel *label = [[UILabel alloc]initWithFr ...
- 解决pymysql.err.InternalError: (1366, "Incorrect string value: '\\xF0\\x9F\\x8C\\xB8' for column 'headline' at row 1")
解决pymysql.err.InternalError: (1366, "Incorrect string value: '\\xF0\\x9F\\x8C\\xB8' for column ...
- Solr7.4的学习与使用
学习的原因: 17年的时候有学习使用过lucene和solr,但是后来也遗忘了,最近公司有个项目需要使用到全文检索,正好也顺便跟着学习一下,使用的版本是Solr7.4的,下载地址:http://arc ...
- orcal创建序列
CREATE SEQUENCE flowjobseq --序列名INCREMENT BY 1 -- 每次加几个 START WITH 2000 -- 从1开始计数 NOMAXVALUE -- 不设置最 ...
- 三、OPENERP 中的对象关系类型
OE中的对象关系一共分四种,one2one,one2many,many2one,many2many.他们的意思分别是一对一,一对多,多对一以及多对多. 我们新建一个模块来测试这四种类型 1.one2o ...
- Jexus高级功能设置
我们对服务器软件Jexus作了简单的介绍,同时我们也对Jexus的整体配置作了详细的讲解,介绍了Jexus的进程守护工具"jws.guard",相信各位读者对于Jexus应该已经有 ...
- (转)MySql数据库4【命令行赋权操作】
MySQL 赋予用户权限命令的简单格式可概括为:grant 权限 on 数据库对象 to 用户 原文:http://www.cnblogs.com/zhuyibo/p/3980328.html 一.g ...
- 19.Class的基本语法
1.简介 JavaScript 语言中,生成实例对象的传统方法是通过构造函数. function Point(x, y) { this.x = x; this.y = y; } Point.proto ...
- 18.async函数
1.含义 async 函数是什么?一句话,它就是 Generator 函数的语法糖. 前文有一个 Generator 函数,依次读取两个文件. var fs = require('fs'); var ...