数组A包含N个整数(可能包含相同的值)。设S为A的子序列且S中的元素是递增的,则S为A的递增子序列。如果S的长度是所有递增子序列中最长的,则称S为A的最长递增子序列(LIS)。A的LIS可能有很多个。例如A为:{1 3 2 0 4},1 3 4,1 2 4均为A的LIS。给出数组A,求A的LIS有多少个。由于数量很大,输出Mod 1000000007的结果即可。相同的数字在不同的位置,算作不同的,例如 {1 1 2} 答案为2。
Input
第1行:1个数N,表示数组的长度。(1 <= N <= 50000) 第2 - N + 1行:每行1个数A[i],表示数组的元素(0 <= A[i] <= 10^9)
Output
输出最长递增子序列的数量Mod 1000000007。
Input示例
5 1 3 2 0 4
Output示例
2
题解:nlogn树状数组维护,维护树状数组管辖区域内的最大值 c[i], 及该最大值相对应的最长上升子序列数量 dp[i].
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N = 5e4+10, mod = 1000000007; 4 int a[N], b[N], c[N], dp[N]; 5 void update(int n, int x, int y){ 6 for(int i = n; i < N; i += i&-i){ 7 if(c[i] < x) 8 c[i] = x, dp[i] = y; 9 else if(c[i] == x){ 10 dp[i] += y; 11 if(dp[i] >= mod) dp[i] %= mod; 12 } 13 } 14 } 15 void get(int n, int& x, int& y){ 16 x = y = 0; 17 for(int i = n; i; i -= i&-i){ 18 if(x < c[i]) 19 x = c[i], y = dp[i]; 20 else if(x == c[i]){ 21 y += dp[i]; 22 if(y >= mod) y %= mod; 23 } 24 } 25 } 26 27 int main(){ 28 int n; scanf("%d", &n); 29 for(int i = 0; i < n; i++) 30 scanf("%d", a+i), b[i] = a[i]; 31 sort(b, b+n); 32 for(int i = 0; i < n; i++) 33 a[i] = lower_bound(b, b+n, a[i])-b+1; 34 int x, y, ans = 0; 35 for(int i = 0; i < n; i++){ 36 get(a[i]-1, x, y); 37 x++; 38 update(a[i], x, x == 1? 1: y); 39 } 40 get(n, x, ans); 41 printf("%d ", ans); 42 return 0; 43 }