FZu Problem 2236 第十四个目标 (线段树 + dp)
题目链接:
题目描述:
给出一个n个数的序列,问这个序列内严格递增序列有多少个?不要求连续
解题思路:
又遇到了用线段树来优化dp的题目,线段树节点里面保存所表达区间里面的方案数。先离散化序列(升序排列),建树,然后按照没有sort前的顺序向线段树里面加点,每次查询小于该数的方案数目+1, 就是当前节点插入进去能影响的方案数目。在线段树对应位置加上新增加的数目即可。
1 #include <cstdio> 2 #include <queue> 3 #include <stack> 4 #include <cmath> 5 #include <cstring> 6 #include <iostream> 7 #include <algorithm> 8 using namespace std; 9 10 #define lson 2*root 11 #define rson 2*root+1 12 typedef __int64 LL; 13 const LL mod = 1000000007; 14 const LL INF= 1e14+7; 15 const int maxn = 100010; 16 17 struct node 18 { 19 int l, r; 20 LL num; 21 int mid () 22 { 23 return (l + r) / 2; 24 } 25 } tree[maxn*4]; 26 LL a[maxn], b[maxn]; 27 28 void build (int root, int l, int r) 29 { 30 tree[root].l = l; 31 tree[root].r = r; 32 tree[root].num = 0; 33 if (l == r) 34 return ; 35 36 build (lson, l, tree[root].mid()); 37 build (rson, tree[root].mid()+1, r); 38 } 39 void Insert (int root, LL x, int y) 40 { 41 if (tree[root].l == tree[root].r && tree[root].l == y) 42 { 43 tree[root].num =(tree[root].num + x) % mod; 44 return ; 45 } 46 47 if (tree[root].mid() >= y) 48 Insert (lson, x, y); 49 else 50 Insert (rson, x, y); 51 tree[root].num = (tree[lson].num + tree[rson].num) % mod; 52 } 53 LL query (int root, int l, int r) 54 { 55 if (tree[root].l == l && tree[root].r == r) 56 return tree[root].num; 57 58 if (tree[root].mid() >= r) 59 return query (lson, l, r); 60 else if (tree[root].mid() < l) 61 return query (rson, l, r); 62 else 63 { 64 LL num = 0; 65 num += query (lson, l, tree[root].mid()); 66 num += query (rson, tree[root].mid()+1, r); 67 return num % mod; 68 } 69 } 70 71 int main () 72 { 73 int n; 74 75 while (scanf ("%d", &n) != EOF) 76 { 77 for (int i=0; i<n; i++) 78 { 79 scanf ("%I64d", &a[i]); 80 b[i] = a[i]; 81 } 82 83 sort (a, a+n); 84 int m = unique (a, a+n) - a; 85 86 LL ans = 0; 87 build (1, 0, m); 88 for (int i=0; i<n; i++) 89 { 90 LL nu, tmp = lower_bound (a, a+m, b[i]) - a; 91 if (tmp == 0) 92 nu = 0; 93 else 94 nu = query (1, 0, tmp-1); 95 96 Insert (1, nu+1, tmp); 97 } 98 99 printf ("%I64d\n", query (1, 0, m)); 100 } 101 return 0; 102 } 103 ///4 1 2 2 3
本文为博主原创文章,未经博主允许不得转载。