[HDU4417]Super Mario(主席树+离散化)

传送门

又是一道主席树模板题,注意数组从0开始,还有主席树耗费空间很大,数组开大点,之前开小了莫名其妙TLE。QAQ

——代码

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define ls son[now][0], l, mid
 5 #define rs son[now][1], mid + 1, r
 6 
 7 using namespace std;
 8 
 9 const int N = 100005;
10 
11 int T, n, m, sz, tot, ans;
12 int a[N], b[N], rt[N], son[10 * N][2], sum[10 * N];
13 
14 inline void build(int &now, int l, int r)
15 {
16     now = ++tot;
17     sum[now] = 0;
18     if(l == r) return;
19     int mid = (l + r) >> 1;
20     build(ls);
21     build(rs);
22 }
23 
24 inline void update(int &now, int l, int r, int last, int x)
25 {
26     now = ++tot;
27     son[now][0] = son[last][0];
28     son[now][1] = son[last][1];
29     sum[now] = sum[last] + 1;
30     if(l == r) return;
31     int mid = (l + r) >> 1;
32     if(x <= mid) update(ls, son[now][0], x);
33     else update(rs, son[now][1], x);
34 }
35 
36 inline void query(int s, int t, int l, int r, int x)
37 {
38     if(l == r)
39     {
40         ans += sum[t] - sum[s];
41         return;
42     }
43     int mid = (l + r) >> 1;
44     if(x <= mid) query(son[s][0], son[t][0], l, mid, x);
45     else
46     {
47         ans += sum[son[t][0]] - sum[son[s][0]];
48         query(son[s][1], son[t][1], mid + 1, r, x);
49     }
50 }
51 
52 inline void clear()
53 {
54     n = m = sz = tot = 0;
55     memset(a, 0, sizeof(a));
56     memset(b, 0, sizeof(b));
57     memset(sum, 0, sizeof(sum));
58     memset(son, 0, sizeof(son));
59     memset(rt, 0, sizeof(rt));
60 }
61 
62 int main()
63 {
64     int i, j = 0, k, x, y, z;
65     scanf("%d", &T);
66     while(T--)
67     {
68         scanf("%d %d", &n, &m);
69         for(i = 1; i <= n; i++) scanf("%d", &a[i]), b[i] = a[i];
70         sort(b, b + n + 1);
71         sz = unique(b + 1, b + n + 1) - (b + 1);
72         tot = 0;
73         build(rt[0], 1, sz);
74         for(i = 1; i <= n; i++)
75         {
76             k = lower_bound(b + 1, b + sz + 1, a[i]) - b;
77             update(rt[i], 1, sz, rt[i - 1], k);
78         }
79         printf("Case %d:\n", ++j);
80         for(i = 1; i <= m; i++)
81         {
82             scanf("%d %d %d", &x, &y, &z);
83             k = upper_bound(b + 1, b + sz + 1, z) - b - 1;
84             if(k)
85             {
86                 ans = 0;
87                 query(rt[x], rt[y + 1], 1, sz, k);
88                 printf("%d\n", ans);
89             }
90             else printf("0\n");
91         }
92     }
93     return 0;
94 }
View Code

 

转载于:https://www.cnblogs.com/zhenghaotian/p/6757340.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值