zoukankan      html  css  js  c++  java
  • 【HDU4991】树状数组

    http://acm.hdu.edu.cn/showproblem.php?pid=4991

    用f[i][j] 表示 前i个数以第i个数结尾的合法子序列的个数,则递推式不难写出:

    f[i][j] = sum(f[k][j - 1]); 其中 k < i, 且a[k] < a[i]; 边界:f[i][1] = 1; 显然需要用数据结构来优化查询

    如果不考虑离散的话,用一个数据结构,记录节点为a[i]的f值,同时维护一个区间f值之和,那么f[i][j] = query(0, a[i] - 1);然后考虑特定的顺序用f值更新数据结构中的信息

    具体见代码(树状数组):

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 #include <map>
     7 #include <stack>
     8 #include <string>
     9 #define mem0(a) memset(a, 0, sizeof(a))
    10 #define mem(a, b) memset(a, b, sizeof(a))
    11 #define lson l, m, rt << 1
    12 #define rson m + 1, r, rt << 1 | 1
    13 #define lr rt << 1
    14 #define rr rt << 1 | 1
    15 #define eps 0.0001
    16 #define lowbit(x) ((x) & -(x))
    17 #define memc(a, b) memcpy(a, b, sizeof(b))
    18 typedef char Str[120];
    19 using namespace std;
    20 #define LL long long
    21 #define DL double
    22 
    23 map<int, int> Hash;
    24 int mol = 123456789;
    25 int a[12000], f[12000][120], b[12000], R[12000], c[120000], N, n, m;
    26 
    27 void init()
    28 {
    29         sort(a + 1, a + 1 + n);
    30         N = 0;
    31         for(int i = 1; i <= n; i++) {
    32                 if(a[i] == a[i - 1] && i > 1) continue;
    33                 Hash[a[i]] =  ++N;
    34         }
    35 }
    36 int query(int p)
    37 {
    38         int ans = 0;
    39         while(p) {
    40                 ans += c[p];
    41                 if(ans >= mol) ans -= mol;
    42                 p -= lowbit(p);
    43         }
    44         return ans;
    45 }
    46 void update(int p, int x)
    47 {
    48         while(p <= N) {
    49                 c[p] += x;
    50                 if(c[p] >= mol) c[p] -= mol;
    51                 p += lowbit(p);
    52         }
    53 }
    54 int main()
    55 {
    56         //freopen("input.txt", "r", stdin);
    57         //freopen("output.txt", "w", stdout);
    58         while(~scanf("%d%d", &n, &m)) {
    59                 for(int i = 1; i <= n; i++) {
    60                         scanf("%d", a + i);
    61                 }
    62                 memc(b, a);
    63                 init();
    64                 mem0(f);
    65                 //puts("d");
    66                 for(int i = 1; i <= n; i++) f[i][1] = 1;
    67                 for(int i = 1; i <= n; i++) R[i] = Hash[b[i]];
    68                 for(int j = 2; j <= m; j++) {
    69                         mem0(c);
    70                         for(int i = 1; i <= n; i++) {
    71                                 f[i][j] = query(R[i] - 1);
    72                                 update(R[i], f[i][j - 1]);
    73                                 //cout<< i<< " "<< j<< " "<< f[i][j]<< endl;
    74                         }
    75                 }
    76                 int ans = 0;
    77                 for(int i = m; i <= n; i++) {
    78                         ans += f[i][m];
    79                         if(ans >= mol) ans -= mol;
    80                 }
    81                 cout<< ans<< endl;
    82         }
    83         return 0;
    84 }
    View Code

    另外用线段树写了一下, 不过超时(2000+ms)了,线段树才不到500ms,由此可见能用树状数组决不用线段树,递归线段树常数太大了

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <algorithm>
      6 #include <map>
      7 #include <stack>
      8 #include <string>
      9 #define mem0(a) memset(a, 0, sizeof(a))
     10 #define mem(a, b) memset(a, b, sizeof(a))
     11 #define lson l, m, rt << 1
     12 #define rson m + 1, r, rt << 1 | 1
     13 #define lr rt << 1
     14 #define rr rt << 1 | 1
     15 #define eps 0.0001
     16 #define lowbit(x) ((x) & -(x))
     17 #define memc(a, b) memcpy(a, b, sizeof(b))
     18 typedef char Str[120];
     19 using namespace std;
     20 #define LL long long
     21 #define DL double
     22 struct seg{
     23         int sum;
     24 }tree[12000 << 2];
     25 map<int, int> Hash;
     26 int mol = 123456789;
     27 int a[12000], f[12000][120], b[12000], R[12000], N, n, m;
     28 
     29 void init()
     30 {
     31         sort(a + 1, a + 1 + n);
     32         N = 0;
     33         for(int i = 1; i <= n; i++) {
     34                 if(a[i] == a[i - 1] && i > 1) continue;
     35                 Hash[a[i]] =  ++N;
     36         }
     37 }
     38 void build(int l, int r, int rt)
     39 {
     40         tree[rt].sum = 0;
     41         if(l == r) return;
     42         int m = (l + r) >> 1;
     43         build(lson);
     44         build(rson);
     45 }
     46 void pushUP(int rt)
     47 {
     48         tree[rt].sum = tree[rt << 1].sum + tree[rt<< 1 | 1].sum;
     49         if(tree[rt].sum >= mol) tree[rt].sum -= mol;
     50 }
     51 void update(int p, int x, int l, int r, int rt)
     52 {
     53         if(l == r) {
     54                 tree[rt].sum += x;
     55                 if(tree[rt].sum >= mol) tree[rt].sum -= mol;
     56                 return;
     57         }
     58         int m = (l + r) >> 1;
     59         if(p <= m) update(p, x, lson);
     60         else update(p, x, rson);
     61         pushUP(rt);
     62 }
     63 int query(int L, int R, int l, int r, int rt)
     64 {
     65         if(L <= l && r <= R) {
     66                 return tree[rt].sum;
     67         }
     68         int m = (l + r) >> 1, res = 0;
     69         if(L <= m) res+= query(L, R, lson);
     70         if(R > m) res += query(L, R, rson);
     71         if(res >= mol) res -= mol;
     72         return res;
     73 }
     74 int main()
     75 {
     76         //freopen("input.txt", "r", stdin);
     77         //freopen("output.txt", "w", stdout);
     78         while(~scanf("%d%d", &n, &m)) {
     79                 for(int i = 1; i <= n; i++) {
     80                         scanf("%d", a + i);
     81                 }
     82                 memc(b, a);
     83                 init();
     84                 mem0(f);
     85                 //puts("d");
     86                 for(int i = 1; i <= n; i++) f[i][1] = 1;
     87                 for(int i = 1; i <= n; i++) R[i] = Hash[b[i]];
     88                 for(int j = 2; j <= m; j++) {
     89                         build(1, N, 1);
     90                         for(int i = 1; i <= n; i++) {
     91                                 if(R[i] > 1) f[i][j] = query(1, R[i] - 1, 1, N, 1);
     92                                 update(R[i], f[i][j - 1], 1, N, 1);
     93                         }
     94                 }
     95                 int ans = 0;
     96                 for(int i = m; i <= n; i++) {
     97                         ans += f[i][m];
     98                         if(ans >= mol) ans -= mol;
     99                 }
    100                 cout<< ans<< endl;
    101         }
    102         return 0;
    103 }
    View Code
  • 相关阅读:
    ES5新特性:理解 Array 中增强的 9 个 API
    ios
    Jquery异步 Deferred Object
    ES5中新增的Array方法详细说明
    Chart
    Angular常用语句
    vticker.js--垂直滚动插件
    <css系列>之css--float总结
    理解boot.img与静态分析Android/linux内核
    理解竞争条件( Race condition)漏洞
  • 原文地址:https://www.cnblogs.com/jklongint/p/3961566.html
Copyright © 2011-2022 走看看