标签:
第1行:1个数N,表示数组的长度。(1 <= N <= 50000) 第2 - N + 1行:每行1个数A[i],表示数组的元素(0 <= A[i] <= 10^9)
输出最长递增子序列的数量Mod 1000000007。
5 1 3 2 0 4
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\n", ans); 42 return 0; 43 }
标签:
原文地址:http://www.cnblogs.com/dirge/p/5958808.html