LightOJ 1085 - All Possible Increasing Subsequences (离散化+树状数组+dp)
Time Limit: 3 second(s) | Memory Limit: 64 MB |
An increasing subsequence from a sequence A1, A2 ... An is defined by Ai1, Ai2 ... Aik, where the following properties hold
- 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
- For the first case, the increasing subsequences are (1), (1, 2), (1), (1, 2), 2.
- Dataset is huge, use faster I/O methods.
题目大意:
就是说,给你一个长度为n的序列,然后,让你求出这个序列中所有的上升子序列的个数
解题思路:
直接把tree[i]当做dp[i]来用,表示的是以a[i]结尾的上升序列的最大个数
代码:
1 # include<iostream> 2 # include<cstdio> 3 # include<algorithm> 4 # include<cstring> 5 6 using namespace std; 7 8 # define MAX 500000+4 9 # define MOD 1000000007 10 11 typedef long long LL; 12 13 LL a[MAX]; 14 LL data[MAX]; 15 int tree[MAX]; 16 int n,cc; 17 18 void discrete() 19 { 20 memset(data,0,sizeof(data)); 21 for ( int i = 0;i < n;i++ ) 22 { 23 data[i] = a[i]; 24 } 25 sort(data,data+n); 26 cc = unique(data,data+n)-data; 27 for ( int i = 0;i < n;i++ ) 28 { 29 a[i] = 1+lower_bound(data,data+cc,a[i])-data; 30 } 31 } 32 33 34 void update ( int pos,int val ) 35 { 36 while ( pos <= n ) 37 { 38 tree[pos]=(tree[pos]+val)%MOD; 39 pos += pos&(-pos); 40 } 41 } 42 43 LL read ( int pos ) 44 { 45 LL sum = 0; 46 while ( pos>0 ) 47 { 48 sum=(sum+tree[pos])%MOD; 49 pos-=pos&(-pos); 50 } 51 return sum%MOD; 52 } 53 54 55 int main(void) 56 { 57 int icase = 1; 58 int t;cin>>t; 59 while ( t-- ) 60 { 61 while ( cin>>n ) 62 { 63 if ( n==0 ) 64 break; 65 LL ans = 0; 66 for ( int i = 0;i < n;i++ ) 67 { 68 cin>>a[i]; 69 } 70 discrete(); 71 memset(tree,0,sizeof(tree)); 72 for ( int i = 0;i < n;i++ ) 73 { 74 update(a[i],read(a[i]-1)+1); 75 } 76 printf("Case %d: ",icase++); 77 cout<<read(cc)%MOD<<endl; 78 } 79 } 80 81 return 0; 82 }