设为首页 加入收藏

TOP

HDU 4417 Super Mario(离线线段树or树状数组)
2015-07-20 17:36:14 来源: 作者: 【 】 浏览:2
Tags:HDU 4417 Super Mario 线段
Problem Description Mario is world-famous plumber. His “burly” figure and amazing jumping ability reminded in our memory. Now the poor princess is in trouble again and Mario needs to save his lover. We regard the road to the boss’s castle as a line (the length is n), on every integer point i there is a brick on height hi. Now the question is how many bricks in [L, R] Mario can hit if the maximal height he can jump is H.
Input The first line follows an integer T, the number of test data.
For each test data:
The first line contains two integers n, m (1 <= n <=10^5, 1 <= m <= 10^5), n is the length of the road, m is the number of queries.
Next line contains n integers, the height of each brick, the range is [0, 1000000000].
Next m lines, each line contains three integers L, R,H.( 0 <= L <= R < n 0 <= H <= 1000000000.)
Output For each case, output "Case X: " (X is the case number starting from 1) followed by m lines, each line contains an integer. The ith integer is the number of bricks Mario can hit for the ith query.

Sample Input
1
10 10
0 5 2 7 5 4 3 8 7 7 
2 8 6
3 5 0
1 3 1
1 9 4
0 1 0
3 5 5
5 5 1
4 6 3
1 5 7
5 7 3

Sample Output
Case 1:
4
0
0
3
1
2
0
1
5
1

普通的线段树果断T成狗,故转向离线。

将砖块高度val和玛丽能跳的高度H都存起来,更新p[k].val<=q[i].h的,区间求和的时候就能保证当前更新的都是小于玛丽能跳的的高度。。。

#include
   
    
#include
    
      #include
     
       #include
      
        #include
       
         typedef long long LL; using namespace std; const int maxn=1e5+10; struct tree{ int l,r; int cnt; }t[maxn<<2]; struct node1{ int val; int pos; bool operator<(const node1 l1)const{ return val
        
         >1; build(rs<<1,l,mid); build(rs<<1|1,mid+1,r); } void update(int rs,int pos) { t[rs].cnt++; if(t[rs].l==t[rs].r) return ; int mid=(t[rs].l+t[rs].r)>>1; if(pos<=mid) update(rs<<1,pos); else update(rs<<1|1,pos); } int query(int l,int r,int rs) { if(t[rs].l==l&&t[rs].r==r) return t[rs].cnt; int mid=(t[rs].l+t[rs].r)>>1; if(r<=mid) return query(l,r,rs<<1); else if(l>mid) return query(l,r,rs<<1|1); else return query(l,mid,rs<<1)+query(mid+1,r,rs<<1|1); } int main() { int t,n,m; int cas=1; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); build(1,1,n); for(int i=1;i<=n;i++) { scanf("%d",&p[i].val); p[i].pos=i; } for(int i=1;i<=m;i++) { scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].h); q[i].id=i; } sort(p+1,p+1+n); sort(q+1,q+1+m); int k=1; for(int i=1;i<=m;i++) { while(k<=n&&p[k].val<=q[i].h) { update(1,p[k].pos); k++; } ans[q[i].id]=query(q[i].l+1,q[i].r+1,1); } printf("Case %d:\n",cas++); for(int i=1;i<=m;i++) printf("%d\n",ans[i]); } return 0; } 
        
       
      
     
    
   

另外树状数组也可以做。类似的单点更新和区间求和问题都可以用树状数组来写。
类似离线线段树的思想将节点和询问保存排序后依次更新,就能保证结果的正确性。
#include
   
    
#include
    
      #include
     
       #include
      
        #include
       
         typedef long long LL; using namespace std; const int maxn=1e5+10; int cnt[maxn]; struct node1{ int val; int pos; bool operator<(const node1 l1)const{ return val
        
         0) { s+=cnt[x]; x-=lowbit(x); } return s; } int main() { int t,n,m; int cas=1; scanf("%d",&t); while(t--) { memset(cnt,0,sizeof(cnt)); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&p[i].val); p[i].pos=i; } for(int i=1;i<=m;i++) { scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].h); q[i].id=i; } sort(p+1,p+1+n); sort(q+1,q+1+m); int k=1; for(int i=1;i<=m;i++) { while(k<=n&&p[k].val<=q[i].h) { update(p[k].pos); k++; } ans[q[i].id]=query(q[i].r+1)-query(q[i].l); } printf("Case %d:\n",cas++); for(int i=1;i<=m;i++) printf("%d\n",ans[i]); } return 0; } 
        
       
      
     
    
   


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇SPOJ - DISUBSTR Distinct Substr.. 下一篇[数位dp] hdu 3886 Final Kichiku..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·Redis 分布式锁全解 (2025-12-25 17:19:51)
·SpringBoot 整合 Red (2025-12-25 17:19:48)
·MongoDB 索引 - 菜鸟 (2025-12-25 17:19:45)
·What Is Linux (2025-12-25 16:57:17)
·Linux小白必备:超全 (2025-12-25 16:57:14)