lightoj 1085 All Possible Increasing Subsequences(递推式+离散化+树状数组维护)
来源:互联网 发布:快递热敏打印软件 编辑:程序博客网 时间:2024/06/06 03:26
An increasing subsequence from a sequence A1, A2 ... An is defined by Ai1, Ai2 ... Aik, where the following properties hold
1. i1 < i2 < i3 < ... < ik and
2. Ai1 < Ai2 < Ai3 < ... < Aik
Now you are given a sequence, you have to find the number of all possible increasing subsequences.
Input
Input starts with an integer T (≤ 10), denoting the number of test cases.
Each case contains an integer n (1 ≤ n ≤ 105) denoting the number of elements in the initial sequence. The next line will contain n integers separated by spaces, denoting the elements of the sequence. Each of these integers will be fit into a 32 bit signed integer.
Output
For each case of input, print the case number and the number of possible increasing subsequences modulo 1000000007.
Sample Input
Output for Sample Input
3
3
1 1 2
5
1 2 1000 1000 1001
3
1 10 11
Case 1: 5
Case 2: 23
Case 3: 7
Notes
1. For the first case, the increasing subsequences are (1), (1, 2), (1), (1, 2), 2.
2. Dataset is huge, use faster I/O methods.
题意:给你一串数字问你这里面有几个严格上升子序列,自己也算一个;
思路:每个数字ai可能很大1e9附近,所以直接用树状数组做会爆内存,那就先离散化一下。。。我跟队友CillyB学的用结构体离散化(其实忘记了以前自己怎么离散化的,觉得这个方法不错就学了过来),如果后面有一个数字,那他前面所有最后一个数字比他小的序列都可以跟他一起构成一个递增序列,比如用dp[i]表示以数字i为结尾序列的长度,举个例子 1 2 3 4 5,dp[1] = 1,dp【2】 = 1 + dp【1】,dp【3】 = 1 + dp【1】 + dp【2】,因为1,2为结尾的序列都可以跟3拼在一起,所以3的序列就是 1 + dp【1】 + dp【2】(加上它本身),这个我们可以用树状数组维护啊!比如更新3这个值,就是求前面有几个比他小的 然后把这个值更新给3这个位置,注意是把前面自序列和更新给3
。。网上有些题解说这是个dp,但是根本没有“决策”的过程啊。。就是个递推式。。
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;const int maxn = 1e5 + 5;const int MOD = 1000000007;int li[maxn], c[maxn];struct node{ int id, v;}a[maxn];int lowbit(int k){ return k & (-k);}void update(int k, int v){ while(k < maxn) { c[k] = (v + c[k])%MOD; k += lowbit(k); }}int sum(int k){ int sum = 0; while(k > 0) { sum = (c[k] + sum)%MOD; k -= lowbit(k); } return sum;}int cmp(node a, node b){ return a.v < b.v;}int main(){ // freopen("123.txt", "w", stdout); int t, n, Case = 0; long long ans; scanf("%d", &t); while(t--) { memset(c, 0, sizeof(c)); memset(li, 0, sizeof(li)); scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &a[i].v), a[i].id = i; sort(a+1, a+1+n, cmp); //先排序 for(int i = 1; i <= n; i++) //这里就是离散化的代码,id就是最开始每个数字的下标,代表了这个数字的“身份” { li[a[i].id] = i; //把每个数字赋值1,2,3,4,达到离散化的标准 if(a[i].v == a[i-1].v) //去重 li[a[i].id] = li[a[i-1].id]; } ans = 0; for(int i = 1; i <= n; i++) { ans = (ans + sum(li[i]-1)+1)% MOD; //这里要查询对前面和-1之前的,因为可能有重复的,这样会多+,比如1,1,2,2 update(li[i], sum(li[i]-1)+1); } printf("Case %d: %lld\n", ++Case, ans); } return 0;}
- lightoj 1085 All Possible Increasing Subsequences(递推式+离散化+树状数组维护)
- LightOJ 1085 All Possible Increasing Subsequences (DP&离散化&树状数组)
- [树状数组]LightOJ 1085 - All Possible Increasing Subsequences
- Lightoj 1085 All Possible Increasing Subsequences (树状数组+DP)
- lightoj 1085 - All Possible Increasing Subsequences 【树状数组优化dp】
- 1085 - All Possible Increasing Subsequences[树状数组]
- LightOJ 1085 - All Possible Increasing Subsequences(DP + 线段树 + 离散)
- lightoj 1085 All Possible Increasing Subsequences
- lightoj1085 - All Possible Increasing Subsequences(树状数组)
- light oj1085All Possible Increasing Subsequences(树状数组+离散化+递推)
- Light OJ 1085 - All Possible Increasing Subsequences
- lightoj1085 All Possible Increasing Subsequences
- lightoj 1085【离散化+树状数组】
- lightoj 1085【离散化+树状数组】
- LightOJ-1085-树状数组,离散化,dp
- HDU 5877 dfs+离散化+树状数组(树上维护)
- hdu 2227 Find the nondecreasing subsequences (树状数组+dp+离散化)
- HDOJ 题目2227 Find the nondecreasing subsequences(树状数组,离散化,DP)
- react-Native ListView中实现单击行展开效果
- 希尔排序
- linux下怎么安装chrome浏览器
- apt-get使用代理
- 归并排序
- lightoj 1085 All Possible Increasing Subsequences(递推式+离散化+树状数组维护)
- 图解Android View的scrollTo(),scrollBy(),getScrollX(), getScrollY()
- 冒泡排序与简单排序
- Android四大组件之------Service
- 完美解决 ListView偶尔爆出的异常:java.lang.IllegalStateException
- Group By的介绍
- 混淆与反编译
- HDU 5919 分块做法
- 12战舰(1)54(4)95(7)160(11)174(14)190(17)204(20)