题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4361

题意概述:

  给出一个长度为N的序列A(A1,A2...AN)。如果序列A不是非降的,你必须从中删去一个数,重复这一操作,直到A非降为止。求有多少种不同的操作方案,答案模10^9+7。

  N<=2000.

分析:

  首先手算一下样例确定一下题意,不同的方案实际上就是删除数字的位置的不同排列。

  当手算答案的时候可以发现我们可以把答案按照最终序列的长度分类。看题目的样子可以搜索但是怎么都弄不出一个子问题来构造方程,答案又可以分类,于是考虑一下容斥。

  首先我们求出f(x)表示长度为x的非降子序列的数量(可以dp搞定,用个树状数组优化一下),然后将其意义令g(x)表示得到长度为x的非降子序列的合法方案数。

  我们观察一下这两个东西:

  g(N) = f(N)

  g(N-1) = f(N-1) - N*g(N) = f(N-1) - N*f(N)

  g(N-2) = f(N-2) - (N-1)*g(N-1) - (N-1)*N*g(N) = f(N-2) - (N-1)*( g(N-1)+N*g(N) ) = f(N-2) - (N-1)*f(N-1)
  ......
  相信聪明机智的你一定发现了什么(滑稽),容斥的时候只要令g(i) = f(i) - (i+1)*f(i+1)就可以辣!
 
  容斥的关键还是在于分类啊
 
 
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cctype>
using namespace std;
const int maxn=;
const int mo=; int N,A[maxn],rank[maxn],f[maxn][maxn],g[maxn],J[maxn];
struct Binary_Index_Tree{
static const int msz=;
int c[msz],n;
Binary_Index_Tree(){
memset(c,,sizeof(c)); n=;
}
void update(int i,int v){
while(i<=n) c[i]=(c[i]+v)%mo,i+=i&(-i);
}
int query(int i){
int re=;
while(i) re=(re+c[i])%mo,i-=i&(-i);
return re;
}
}bit[maxn]; bool nega;
void _scanf(int &x)
{
x=,nega=;
char ch=getchar();
while((ch<''||ch>'')&&ch!='-') ch=getchar();
if(ch=='-') nega=,ch=getchar();
while(ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
if(nega) x=-x;
}
void data_in()
{
_scanf(N);
for(int i=;i<=N;i++) _scanf(A[i]);
}
void work()
{
memcpy(rank,A,sizeof(A));
sort(rank+,rank+N+);
int cnt=unique(rank+,rank+N+)-rank-;
for(int i=;i<=N;i++) bit[i].n=cnt;
for(int i=;i<=N;i++)
A[i]=lower_bound(rank+,rank+cnt+,A[i])-rank;
for(int i=;i<=N;i++){
f[i][]=;
for(int j=;j<=i;j++)
f[i][j]=(f[i][j]+bit[j-].query(A[i]))%mo;
for(int j=;j<=i;j++)
bit[j].update(A[i],f[i][j]);
}
for(int i=;i<=N;i++)
for(int j=;j<=i;j++) g[j]=(g[j]+f[i][j])%mo;
J[]=;
for(int i=;i<=N;i++) J[i]=1ll*i*J[i-]%mo;
for(int i=;i<=N;i++) g[i]=1ll*g[i]*J[N-i]%mo;
for(int i=;i<N;i++) g[i]=(g[i]-1ll*g[i+]*(i+)%mo+mo)%mo;
int ans=;
for(int i=;i<=N;i++) ans=(ans+g[i])%mo;
printf("%d\n",ans);
}
int main()
{
data_in();
work();
return ;
}

BZOJ 4361 isn 容斥+dp+树状数组的更多相关文章

  1. [CF1086E]Beautiful Matrix(容斥+DP+树状数组)

    给一个n*n的矩阵,保证:(1)每行都是一个排列 (2)每行每个位置和上一行对应位置不同.求这个矩阵在所有合法矩阵中字典序排第几.考虑类似数位DP的做法,枚举第几行开始不卡限制,那么显然之前的行都和题 ...

  2. 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[ ...

  3. bzoj 1264 [AHOI2006]基因匹配Match(DP+树状数组)

    1264: [AHOI2006]基因匹配Match Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 793  Solved: 503[Submit][S ...

  4. BZOJ 1264: [AHOI2006]基因匹配Match 树状数组+DP

    1264: [AHOI2006]基因匹配Match Description 基因匹配(match) 卡卡昨天晚上做梦梦见他和可可来到了另外一个星球,这个星球上生物的DNA序列由无数种碱基排列而成(地球 ...

  5. 树形DP+树状数组 HDU 5877 Weak Pair

    //树形DP+树状数组 HDU 5877 Weak Pair // 思路:用树状数组每次加k/a[i],每个节点ans+=Sum(a[i]) 表示每次加大于等于a[i]的值 // 这道题要离散化 #i ...

  6. 【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 ...

  7. 奶牛抗议 DP 树状数组

    奶牛抗议 DP 树状数组 USACO的题太猛了 容易想到\(DP\),设\(f[i]\)表示为在第\(i\)位时方案数,转移方程: \[ f[i]=\sum f[j]\;(j< i,sum[i] ...

  8. BZOJ.4361.isn(DP 树状数组 容斥)

    题目链接 长度为\(i\)的不降子序列个数是可以DP求的. 用\(f[i][j]\)表示长度为\(i\),结尾元素为\(a_j\)的不降子序列个数.转移为\(f[i][j]=\sum f[i-1][k ...

  9. BZOJ 4361 isn | DP 树状数组

    链接 BZOJ 4361 题面 给出一个长度为n的序列A(A1,A2...AN).如果序列A不是非降的,你必须从中删去一个数, 这一操作,直到A非降为止.求有多少种不同的操作方案,答案模10^9+7. ...

随机推荐

  1. OC录制小视频

    OC录制小视频 用 AVCaptureSession + AVCaptureMovieFileOutput 来录制视频,并通过AVAssetExportSeeion 手段来压缩视频并转换为 MP4 格 ...

  2. python3爬取全站美眉图片

    爬取网站:https://www.169tp.com/xingganmeinv 该网站美眉图片有数百页,每页24张,共上万张图片,全部爬取下来 import urllib.request import ...

  3. PHP的发展历程

    PHP的发展历程 了解一门语言,我们必须知道这门语言的发展史,现在我通过版本的变化以时间轴的形式来说明PHP的发展历程. 1.1995年初PHP1.0诞生 Rasmus Lerdof发明了PHP,这是 ...

  4. hadoop生态搭建(3节点)-16.elk配置

    # ==================================================================ELK环境准备 # 修改文件限制 # * 代表Linux所有用户 ...

  5. Python学习:11.Python装饰器讲解(二)

    回顾 上一节我们进行了Python简单装饰器的讲解,但是python的装饰器还有一部分高级的使用方式,这一节就针对python装饰器高级部分进行讲解. 为一个函数添加多个装饰器 今天,老板又交给你一个 ...

  6. Python学习笔记四:列表,购物车程序实例

    列表 切片 中括号,逗号分隔,可以一次取出多个元素,起始位置包括,结束位置不包括(顾头不顾尾) 如果取最后一个,而且不知道列表长度,可以使用负数(-1是最后一个,以此类推) 如果取最后几个,记住从左往 ...

  7. tomcat搭建https服务(非自签发)

    平时做自己的web demo基本上都是用http协议进行访问. 但是正式情况基本上都是https进行访问,所以掌握https的配置是很关键的. 需要准备的材料: 一台可以可以外网访问的远程服务器 to ...

  8. 使用bison和yacc制作脚本语言(3)

    我们现在已经可以写好文法了,下一步我们打算开始正式创建工程了 在工程目录下,我们创建如下文件夹 ./include ./memory ./ms include文件夹下我们将放头文件 memory是内存 ...

  9. EOJ Monthly 2019.3 A

    A. 钝角三角形 单点时限: 3.0 sec 内存限制: 512 MB QQ 小方以前不会判断钝角三角形,现在他会了,所以他急切的想教会你. 如果三角形的三边长分别为 a, b, c (a≤b≤c), ...

  10. JAVA8 Stream API的使用

    /** * @auther hhh * @date 2018/12/31 12:48 * @description Stream流:用来处理数组.集合的API * 1.不是数据结构,没有内部存储(只是 ...