/* * 说什么好呢?对于这个题目写了好几天 感觉 dp + 线段树 总有道关卡,一直突破不了,总是在漫无边际的沼泽挣扎 * 因为这样心情严重受挫 * 区间的维护总是很难跟dp 联系在一起,单单的区间维护是会的,但是感觉牵扯上了dp,就什么都不会了,dp 。。一个字,怕 * 或许挣扎就是收获吧,渐渐地应该学会如何取分析问题,如何看待wrong * 一开始敲代码的时候。我就是完全没有理解题目,想当然的理解题目是一个悲剧阿 * * 题目求的是一个序列中非递减的所有序列组合的和 */ #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #define L int #define LL(x) ((x) << 1) #define RR(x) ((x) << 1 | 1) using namespace std; const int N = 100005; const int mod = 1000000007; struct Seg_tree { int l, r; L sum; int mid() { return (l + r) >> 1; } } tree[3 * N]; int pos[N]; int df1[N]; int df2[N]; L dp[N]; inline void Build(int l, int r, int node) { tree[node].l = l; tree[node].r = r; tree[node].sum = 0; if (l == r) return; int mid = (l + r) >> 1; Build(l, mid, LL(node)); Build(mid + 1, r, RR(node)); } inline void Update(int dx, int node, int sum) { if (tree[node].l == tree[node].r && tree[node].l == dx) { tree[node].sum =(tree[node].sum + sum) % mod; // 这里不加mod wrong,一个区间要保证在mod的范围 return; } /* if (tree[node].sum != -1) { tree[LL(node)].sum = tree[RR(node)].sum = tree[node].sum; tree[node].sum = -1; } */ int mid = tree[node].mid(); if(dx <= mid) Update(dx, LL(node), sum); else Update(dx, RR(node), sum); /* if (r <= mid) { Update(l, r, LL(node), sum); } else if (l > mid) { Update(l, r, RR(node), sum); } else { Update(l, mid, LL(node), sum); Update(mid + 1, r, RR(node), sum); } */ tree[node].sum = (tree[LL(node)].sum + tree[RR(node)].sum) % mod; // 区间维护 } inline int Query(int l, int r, int node) { if (l <= tree[node].l && tree[node].r <= r) { return tree[node].sum; } /* if (tree[node].sum != -1) { tree[LL(node)].sum = tree[RR(node)].sum = tree[node].sum; tree[node].sum = -1; } */ int mid = tree[node].mid(); if (r <= mid) { return Query(l, r, LL(node)); } else if (l > mid) { return Query(l, r, RR(node)); } else { return (Query(l, mid, LL(node)) + Query(mid + 1, r, RR(node))) % mod ; } } inline int Bin(int x, int len){ // 二分 int low = 0; int high = len - 1; while(low <= high){ int mid = (low + high) >> 1; if(pos[mid] == x) return mid; if(pos[mid] < x){ low = mid + 1; } else{ high = mid - 1; } } return -1; } int main() { int n; while(scanf("%d", &n) != EOF){ for(int i = 0; i < n; i++){ scanf("%d", &df1[i]); df2[i] = df1[i]; } sort(df2, df2 + n); int len = 0; for(int i = 0; i < n; i++){ if(i == 0 || df2[i] != df2[i - 1]) pos[len++] = df2[i]; } // 离散化 Build(0, len - 1, 1); //memset(dp, 0, sizeof(dp)); for(int i = 0; i < n; i++){ int r = Bin(df1[i], len); //printf("r :: %d df1[i] :: %d/n", r, df1[i]); L sum = (Query(0, r, 1) + 1 ) % mod; //printf("sum :: %d/n", sum); /* if(sum == 0){ sum = 1; dp[r] =( dp[r] + sum) % mod; Update(r, 1, 1); continue; } */ //dp[r] = (dp[r] + sum) % mod; Update(r, 1, sum); } printf("%d/n", Query(0, len - 1, 1)); /*// 这里太麻烦了。。。其实就是统计一个区间的和 L sum = 0; for(int i = 0; i < len; i++){ //printf("i :: %d dp[i] :: %d/n", i, dp[i]); sum = (sum + dp[i]) % mod; } printf("%d/n", sum); */ } } //9 8 5 32 1 5 4 6 2 1