传送门

DP

十分显然的DP,但是不好写

设 f[ i ] 表示以第 i 个数作结尾时的方案数,原序列为 a

如果不考虑相同的序列:

  那么转移就是 Σ f[ j ] (0< j < i && a [ j ] < a [ i ])

  复杂度为 O(n^2)

  考虑优化:

    先去重 ,得到数组 b

    每次把f [ i ] 加到树状数组里 a [ i ]的值 在 b 中的位置 的位置

    那么 f [ i ] 就等于 query(a [ i ] 的值在 b 中的位置-1) (query为树状数组的询问操作)

    (上两行很重要,自己在脑子里想象一下,一定要理解原因)

然后考虑去掉相同的序列

很简单

只要每次更新完 f [ i ] 时把 f [ i ] 减去前面 a 中所有值为 a[ i ] 的位置(设为 j)

的 f[ j ]的和(还是要在脑子里想象一下...或者看代码来理解...

最后注意要减去长度为 1 的方案数以及一些细节

代码其实不长

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
const int N=1e5+;
const int mo=1e9+;
int n,a[N],f[N],b[N],t[N],las[N],m,ans;
//t是树状数组的数组,las[i]是前面a中所有值为a[i]的位置(设为j)的f[j]的和
inline int query(int x)
{
int res=;
while(x)
{
res=(res+t[x])%mo;
x-=x&-x;
}
return res;
}
inline void add(int x,int v)
{
while(x<=m)
{
t[x]=(t[x]+v)%mo;
x+=x&-x;
}
}
int main()
{
cin>>n;
for(int i=;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i]; sort(b+,b+n+); m=unique(b+,b+n+)-b-;//去重
for(int i=;i<=n;i++)
{
int k=lower_bound(b+,b+m+,a[i])-b;//找到a[i]在b中的位置 f[i]=(f[i]+query(k-)+)%mo;
f[i]-=las[k];
if(f[i]<) f[i]+=mo; ans=(ans+f[i])%mo;
add(k,f[i]);
las[k]=(las[k]+f[i])%mo;
}
ans-=m; if(ans<) ans+=mo;//减去长度为1的方案数
cout<<ans;
return ;
}

P3970 [TJOI2014]上升子序列的更多相关文章

  1. bzoj5157: [Tjoi2014]上升子序列(树状数组LIS)

    5157: [Tjoi2014]上升子序列 题目:传送门 题解: 学一下nlogn的树状数组求最长上生子序列就ok(%爆大佬) 离散化之后,用一个数组记录一下,直接树状数组做 吐槽:妈耶...一开始不 ...

  2. BZOJ5157 & 洛谷3970:[TJOI2014]上升子序列——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=5157 https://www.luogu.org/problemnew/show/P3970 给定 ...

  3. 【bzoj5157】[Tjoi2014]上升子序列 树状数组

    题目描述 求一个数列本质不同的至少含有两个元素的上升子序列数目模10^9+7的结果. 题解 树状数组 傻逼题,离散化后直接使用树状数组统计即可.由于要求本质不同,因此一个数要减去它前一次出现时的贡献( ...

  4. 【[TJOI2014]上升子序列】

    这本质上是一个\(dp\) 如果没有"两个上升子序列相同,那么只需要计算一次"这一个性质,那么就很好做了,我们用\(dp[i]\)表示以\(i\)结尾的上升子序列个数,那么就有\( ...

  5. [TJOI2014] 上升子序列

    刚刚做的时候一看:这不是个傻逼题吗hhhhh....然后发现写完了过不了样例,仔细一看题:同构的算一种. 这可咋办啊? 其实很简单,设f[i] 为 以a[i] 结尾的上升子序列个数,我们考虑当前如果算 ...

  6. BZOJ5157 [Tjoi2014]上升子序列 【树状数组】

    题目链接 BZOJ5157 题解 我们只需计算每个位置为开头产生的贡献大小,就相当于之后每个大于当前位置的位置产生的贡献 + 1之和 离散化后用树状数组维护即可 要注意去重,后面计算的包含之前的,记录 ...

  7. 用python实现最长公共子序列算法(找到所有最长公共子串)

    软件安全的一个小实验,正好复习一下LCS的写法. 实现LCS的算法和算法导论上的方式基本一致,都是先建好两个表,一个存储在(i,j)处当前最长公共子序列长度,另一个存储在(i,j)处的回溯方向. 相对 ...

  8. codevs 1576 最长上升子序列的线段树优化

    题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...

  9. [LeetCode] Arithmetic Slices II - Subsequence 算数切片之二 - 子序列

    A sequence of numbers is called arithmetic if it consists of at least three elements and if the diff ...

随机推荐

  1. 在JAVA中,String,Stringbuffer,StringBuilder 的区别

    首先是,String,StringBuffer的区别 两者的主要却别有两方面,第一是线程安全方面,第二是效率方面 线程安全方面: String  不是线程安全的,这意味着在不同线程共享一个String ...

  2. day70-oracle PLSQL_01基本语法

    PLSQL是一种程序,和java一样都是一种程序. sql developer是基于java的jdbc连接数据库.根据java的jdbc,只要有数据库的驱动,就可以连接这个数据库.这个工具默认不需要任 ...

  3. C++ 面向对象: I/O对象的应用

    1. 补充完整从text.txt文件读取数据后,再写入in.txt文件.2. 完成从text.txt文件读取数据后,进行排序,再写入in.txt文件.数据量自行设定.3. 请解决在主程序文件中加载多个 ...

  4. python中list的使用

    1.list(列表)是一种有序的集合,可以随时添加.修改.删除其中的元素. 举例:listClassName = ['Jack','Tom','Mark'] 列表可以根据索引获取元素,如:listCl ...

  5. Hive安装及配置

    第一步:下载hive并解压 tar zxvf hive-0.8.1-bin.tar.gz 重命名: mv hive-0.8.1-bin hive 给权限:chown hadoop:hadoop hiv ...

  6. SDUT 1489 求二叉树的先序遍历 (中序后序还原二叉树)

    求二叉树的先序遍历 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem Description  已知一 ...

  7. IntelliJ IDEA打可运行jar包时的错误

    1.[ERROR] 'build.resources.resource.directory'  解决:需要在pom.xml的project->build->resources节点下,加入以 ...

  8. Sublime Text PHP Mac系统环境配置

    Mac系统对于PHP运行非常友好,我们只需要进行简单的配置便可以开始进行使用,本篇文章将一步一步地介绍Apache.PHP和MySQL的安装与配置,为开始进行开发铺好路 Apache 启动Apache ...

  9. Java50道经典习题-程序36 移动位置

    题目:有n个整数,使其前面各数顺序向后移m个位置,最后m个数变成最前面的m个数 分析:比如有4个数n=4; 1 2 3 4 各个数向后移动2位m=2,变为 1 2 3 4 将最后m个数,即将最后2个数 ...

  10. 对bookinfo.dat的说明

    作者:马健邮箱:stronghorse_mj@hotmail.com发布:2008.08.03 现在论坛推出的下载工具五花八门,但是有不少都忽视了bookinfo.dat的生成,因此有必要说明一下这个 ...