FZu Problem 2236 第十四个目标 (线段树 + dp)

题目链接:

  FZu  Problem 2236 第十四个目标

题目描述:

  给出一个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

 

posted @ 2016-05-16 12:17  罗茜  阅读(248)  评论(0编辑  收藏  举报