BZOJ 4361 isn | DP 树状数组
链接
题面
给出一个长度为n的序列A(A1,A2...AN)。如果序列A不是非降的,你必须从中删去一个数,
这一操作,直到A非降为止。求有多少种不同的操作方案,答案模10^9+7。
N <= 2000。
题解
中国非著名数学老师张军说过:正难则反……
答案就是所有最后剩下一个非降序列的方案 - 不合法的最后剩下一个非降序列的方案。
什么是不合法的、最后剩下一个非降序列的方案呢?就是中间过程中已经形成非降序列的方案。它们的共同特点就是——若最后剩下的序列长度为i,则一定是长度为(i + 1)的另一个非降序列删去(i + 1)个数中的一个数后形成的。要把这部分减去。
设f[i]表示长为i的非降序列的个数。
所以答案就是$$ans = \sum_{i = 1}{n} (f[i] * (n - i) ! - f[i + 1] * (n - i - 1) ! * (i + 1)$$。
问题就是怎么求出f[i]。
设g[i][j]为长为i、最后一位是原序列中第j个数的不降序列数。
则有$$g[i][j] = \sum_{k \le j, a[k] \le a[j]} g[i - 1][k]$$。
求g可以用树状数组优化,总复杂度\(O(n^2 \log n)\)
那么f[i] 就是所有 g[i][j] 之和。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
#define enter putchar('\n')
#define space putchar(' ')
template <class T>
void read(T &x){
char c;
bool op = 0;
while(c = getchar(), c > '9' || c < '0')
if(c == '-') op = 1;
x = c - '0';
while(c = getchar(), c >= '0' && c <= '9')
x = x * 10 + c - '0';
if(op) x = -x;
}
template <class T>
void write(T x){
if(x < 0) putchar('-'), x = -x;
if(x >= 10) write(x / 10);
putchar('0' + x % 10);
}
const int N = 2005, P = 1000000007;
int n, a[N], g[N][N], f[N], lst[N], idx, sum[N];
ll ans, fac[N];
void add(int p, int x){
while(p <= n) sum[p] = (sum[p] + x) % P, p += p & -p;
}
int ask(int p){
int ret = 0;
while(p) ret = (ret + sum[p]) % P, p -= p & -p;
return ret;
}
int main(){
read(n);
for(int i = 1; i <= n; i++)
read(a[i]), lst[i] = a[i];
sort(lst + 1, lst + n + 1);
idx = unique(lst + 1, lst + n + 1) - lst - 1;
for(int i = 1; i <= n; i++)
a[i] = lower_bound(lst + 1, lst + idx + 1, a[i]) - lst;
for(int i = 1; i <= n; i++)
g[1][i] = 1;
for(int i = 2; i <= n; i++){
memset(sum, 0, sizeof(sum));
for(int j = 1; j <= n; j++)
g[i][j] = ask(a[j]), add(a[j], g[i - 1][j]);
}
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
f[i] = (f[i] + g[i][j]) % P;
fac[0] = 1;
for(int i = 1; i <= n; i++)
fac[i] = fac[i - 1] * i % P;
for(int i = 1; i <= n; i++)
ans = ((ans + f[i] * fac[n - i] % P
- f[i + 1] * fac[n - i - 1] % P * (i + 1) % P) % P + P) % P;
write(ans), enter;
return 0;
}
BZOJ 4361 isn | DP 树状数组的更多相关文章
- BZOJ.4361.isn(DP 树状数组 容斥)
题目链接 长度为\(i\)的不降子序列个数是可以DP求的. 用\(f[i][j]\)表示长度为\(i\),结尾元素为\(a_j\)的不降子序列个数.转移为\(f[i][j]=\sum f[i-1][k ...
- bzoj 1264 [AHOI2006]基因匹配Match(DP+树状数组)
1264: [AHOI2006]基因匹配Match Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 793 Solved: 503[Submit][S ...
- 树形DP+树状数组 HDU 5877 Weak Pair
//树形DP+树状数组 HDU 5877 Weak Pair // 思路:用树状数组每次加k/a[i],每个节点ans+=Sum(a[i]) 表示每次加大于等于a[i]的值 // 这道题要离散化 #i ...
- 【bzoj2274】[Usaco2011 Feb]Generic Cow Protests dp+树状数组
题目描述 Farmer John's N (1 <= N <= 100,000) cows are lined up in a row andnumbered 1..N. The cows ...
- 奶牛抗议 DP 树状数组
奶牛抗议 DP 树状数组 USACO的题太猛了 容易想到\(DP\),设\(f[i]\)表示为在第\(i\)位时方案数,转移方程: \[ f[i]=\sum f[j]\;(j< i,sum[i] ...
- BZOJ 4361 isn 容斥+dp+树状数组
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4361 题意概述: 给出一个长度为N的序列A(A1,A2...AN).如果序列A不是非降的 ...
- BZOJ.4553.[HEOI2016&TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点)
题目链接:BZOJ 洛谷 \(O(n^2)\)DP很好写,对于当前的i从之前满足条件的j中选一个最大值,\(dp[i]=d[j]+1\) for(int j=1; j<i; ++j) if(a[ ...
- bzoj 3594: [Scoi2014]方伯伯的玉米田 dp树状数组优化
3594: [Scoi2014]方伯伯的玉米田 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 314 Solved: 132[Submit][Sta ...
- bzoj 1264 [AHOI2006]基因匹配Match dp + 树状数组
思路:好难想啊, 考虑到应该从每个数字只有5个数字下手, 但是不知道到底该怎么写.. 首先我们将第一个串按数字的种类分类, 每一类里面有5个, 然后将第二个串里面的数字一个一个加,如果一个加入的第 i ...
随机推荐
- vue-cli 动态绑定图片失败
1.template 中引用图片,第一个为固定路径,第二个为动态绑定路径 eg: <img src="XXXXXX.png" alt=""> < ...
- Luogu P2055 [ZJOI2009]假期的宿舍
一道网络有关的问题,还是一句话 网络流重在建模! 这里主要讲两种算法. 1.二分图匹配: 分析题意,我们可以知道题目要求是让所有留在学校的人都能有床睡 而 所有留在学校的人=本校不回家的人+外校的人: ...
- 分享一下个人学PS的过程
得知Photoshop这款软件是在上大学的时候,2010年.学校学生会的科技部纳新,要求新人会PPT.word.Excel和Photoshop.当时有一个Photoshop大神,成为了学生会科技部的主 ...
- Zabbix实战-简易教程--大型分布式监控系统实现Agent批量快速接入
一.分布式架构 相信使用zabbix的大神都熟悉他的分布式架构,分布式的优势相当明显,分而治之.比如目前我的架构图如下: 那么,对将要接入监控系统的任何一个agent如何快速定位,并进行接入呢? 问 ...
- 设计模式 笔记 抽象工厂模式 Abstract Factory
//---------------------------15/04/09---------------------------- //Abstract Factory 抽象工厂----对象创建型模式 ...
- Android Studio开发实用网站收集
重点 1.Android Studio 调试技巧-断点调试 http://blog.csdn.net/qq_32452623/article/details/53769708 2.android st ...
- python+Selenium 环境搭建
一.下载相关软件 1.python http://python.org/getit/ 2.setuptools http://pypi.python.org/pypi/setuptools 3.pip ...
- Java并发编程(详解wait(), notify(),sleep())
http://blog.csdn.net/luckyzhoustar/article/details/48179161
- linux内核分析第三次实验
http://blog.sina.com.cn/s/blog_78e559950102wo67.html
- js生成uuid代码
function uuid() { var s = []; var hexDigits = "0123456789abcdef"; for (var i = 0; i < 3 ...