【BZOJ4361】isn
题目
做法
\(dp_{i,j}\)表示以\(i\)结尾\(j\)长度,树状数组\(tree_{i,j}\)表长度为\(i\),以\(<=j\)结尾的个数,显然\(dp_{i,j}=\sum\limits_{k=1}^{pos[i]}tree[j-1][k]\)
从而\(O(n^2logn)\)得到每个长度不下降子序列个数
\(ans=\sum\limits_{i=1}^n(g[i]\times (n-i)!-g[i+1]\times (n-i-1)!\times (i+1))\)
怎么理解这句话呢?\(g[i]\)表长度\(i\)的个数,我们确定了长度,自然能得到这个长度的方案数,然而有些是不合法的,因为之前已经得到不下降了不能再删
那就减去\(i+1\)的个数到\(i\)的转移
My complete code
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
typedef long long LL;
const LL maxn=3000;
const LL p=1e9+7;
inline LL Read(){
LL x(0),f=1; char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') f=-1; c=getchar();
}
while(c>='0'&&c<='9')
x=(x<<3)+(x<<1)+c-'0',c=getchar();
return x*f;
}
LL n,cnt,ans;
LL tree[maxn][maxn],a[maxn],b[maxn],g[maxn],dp[maxn][maxn],pos[maxn],jc[maxn];
inline LL Lowbit(LL x){
return x&(-x);
}
inline LL Query(LL len,LL x){
LL ret(0);
for(;x;x-=Lowbit(x))
ret=(ret+tree[len][x]);
return ret;
}
inline void Add(LL len,LL x,LL val){
for(;x<=n;x+=Lowbit(x))
tree[len][x]=(tree[len][x]+val)%p;
}
int main(){
n=Read();
for(LL i=1;i<=n;++i)
a[i]=b[i]=Read();
sort(b+1,b+1+n);
cnt=unique(b+1,b+1+n)-b-1;
Add(0,1,1);
for(LL i=1;i<=n;++i){
pos[i]=lower_bound(b+1,b+1+cnt,a[i])-b;
for(LL j=i;j>=1;--j){
dp[i][j]=Query(j-1,pos[i])%p;
Add(j,pos[i],dp[i][j]);
}
}
for(LL i=1;i<=n;++i)
for(LL j=1;j<=n;++j)
g[i]=(g[i]+dp[j][i])%p;
jc[1]=1;
for(LL i=2;i<=n;++i)
jc[i]=jc[i-1]*i%p;
for(LL i=1;i<=n;++i)
ans=(ans+g[i]*jc[n-i]%p-g[i+1]*jc[n-i-1]%p*(i+1)%p+p)%p;
printf("%lld\n",ans);
return 0;
}
【BZOJ4361】isn的更多相关文章
- 【BZOJ4361】isn 动态规划+树状数组+容斥
[BZOJ4361]isn Description 给出一个长度为n的序列A(A1,A2...AN).如果序列A不是非降的,你必须从中删去一个数, 这一操作,直到A非降为止.求有多少种不同的操作方案, ...
- 【BZOJ4361】isn(动态规划,容斥)
[BZOJ4361]isn(动态规划,容斥) 题面 BZOJ 题解 首先我们如果确定了一个不降序列,假设它的长度为\(i\), 那么可行的方案数为\(i*(n-i)!\),但是这样有一些非法的情况,即 ...
- Python高手之路【六】python基础之字符串格式化
Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...
- 【原】谈谈对Objective-C中代理模式的误解
[原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...
- 【原】FMDB源码阅读(三)
[原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...
- 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新
[原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...
- 【调侃】IOC前世今生
前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...
- Python高手之路【三】python基础之函数
基本数据类型补充: set 是一个无序且不重复的元素集合 class set(object): """ set() -> new empty set object ...
- Python高手之路【一】初识python
Python简介 1:Python的创始人 Python (英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种解释型.面向对象.动态数据类型的高级程序设计语言,由荷兰人Guido ...
随机推荐
- ubuntu下USB连接Android手机
初始工作:将Android手机通过usb连接到电脑,之后点击VM-Removable Devices-google Android - Connect,即可. 若通过usb连接到电脑,Removabl ...
- Android 图片查看器
1 http://blog.csdn.net/wang8512945/article/details/8075413 2 http://blog.csdn.net/lcore/article/deta ...
- matlab-非线性方程求根函数及函数曲线绘制
Matlab中提供了很多求解非线性方程(y=f(x))的函数,刚開始使用,真的很困惑.全部.这里依据matlab的help文档对这些函数做一些小小的总结 fsolve函数 用来求解非线性方程组:F(x ...
- mysql中的for update
Select…For Update语句的语法与select语句相同,只是在select语句的后面加FOR UPDATE [NOWAIT]子句. 该语句用来锁定特定的行(如果有where子句,就是满足w ...
- hdu 3172 Virtual Friends(并查集,字典树)
题意:人与人交友构成关系网,两个人交友,相当于两个朋友圈的合并,问每个出两人,他们目前所在的关系网中的人数. 分析:用并查集,其实就是求每个集合当前的人数.对于人名的处理用到了字典树. 注意:1.题目 ...
- oracle查询当前会话数量
SELECT a.inst_id,sid,username,event,sql_id,a.PROGRAM FROM gv$session a WHERE a.STATUS='ACTIVE' AND u ...
- CyclicBarrier的工作原理及其实例
CyclicBarrier是多线程中一个重要的类,主要用于线程组内部之间的线程的相互等待问题. 1.CyclicBarrier的工作原理 CyclicBarrier大致是可循环利用的屏障,顾名思义,这 ...
- git add . git add -u git add -A命令区别图解
git版本不同会有所区别: Git Version 1.x: Git Version 2.x: git add . 修改(modified)以及新文件(new),但不包括被删除的文件. git ...
- diamond源码阅读-目录监控
PathNode(Path)StandardWatchEventKind(WatchEvent)Watchable(WatchKey WatchService WatchEvent)WatchKey( ...
- _DataStructure_C_Impl:图的最小生成树
#include<stdio.h> #include<stdlib.h> #include<string.h> typedef char VertexType[4] ...