【树状数组】51nod 1376 最长递增子序列的数量
思路:dp[i]由dp[i-1]而来,统计小于a[i]的位置k,且dp[k]+1=dp[i]的所有个数即可。
代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; template <class T> inline bool rd(T &ret) { char c; int sgn; if(c = getchar() , c == EOF) return false; while(c != '-' && (c < '0' || c > '9')) c = getchar(); sgn = (c == '-') ? -1 : 1; ret = (c == '-') ? 0 : (c - '0'); while(c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0'); ret *= sgn; return true; } const int MAX_N = 500007; const int N = MAX_N; const int MOD = (int)1e9 + 7; struct Bit { int bit[N]; void clear() { memset(bit, 0, sizeof bit); } void add(int i, int v) { for (;i < N; i += i & -i) if (v > bit[i]) bit[i] = v; } int query(int i) { int re = 0; for (;i > 0; i -= i & -i) re = max(re, bit[i]); return re; } }; int n; int a[MAX_N], b[MAX_N], dp[MAX_N]; int pre[MAX_N]; #include <vector> vector<int> v[MAX_N]; void Main() { rd(n); for (int i = 0; i < n; ++i) rd(a[i]), b[i] = a[i]; sort(b, b + n); int m = unique(b, b + n) - b; for (int i = 0; i < n; ++i) a[i] = lower_bound(b, b + m, a[i]) - b + 2; Bit B; int ans = 0; for (int i = 0; i < n; ++i) { dp[i] = B.query(a[i] - 1); int now = 0; for (int j = 0; j < v[dp[i]].size(); ++j) { int u = v[dp[i]][j]; if (a[u] < a[i]) { now = (now + pre[u]) % MOD; } } if (dp[i] == 0) pre[i] = 1; else pre[i] = now; ans = max(ans, dp[i] + 1); v[dp[i] + 1].push_back(i); B.add(a[i], dp[i] + 1); } int res = 0; for (int i = 0; i < n; ++i) if (ans == dp[i] + 1) res = (res + pre[i]) % MOD; printf("%d\n", res); return ; } int main() { Main(); return 0; }