zoukankan      html  css  js  c++  java
  • HDU 4417 BIT or ST

    Super Mario

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 6804    Accepted Submission(s): 2920


    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
     
    Source
     也是一道很好的区间求和的题目,与那道pingpong很相似可惜我思路错了越写越复杂,最后看的别人的思路,真是惭愧= =
    难点不在于写区间求和的数据结构,这个很容易完成无论是BIT还是线段树代码量都不会很大,难点在于将题目所给的模型转化为容易求解的方式。
    题目很容易看懂,从左至右给每个位置一个值,接着进行m次询问,(l,r,h) 求[l,r]位置之间<=h的值的位置总数。
    暴力的话显然会超时,注意一点h可能会很大达到1e9但是n和m最大1e5,一开始我想的是将h值进行离散化操作保持小的数离散化之后仍然是较小的数,
    然后定义线段树以H值为区间,最多10w个H,所以H最大10w,然后进行两次BIT算出L[i],R[i],表示li,ri之前满足要求的数,最后进行相减。
    ,可后来发现不对,因为询问的时候可能出现不属于离散化的n个数的数,这样的话除非对着10w个数也进行离散化,代码很冗余。
    看了别人的思路后恍然大悟,正好和我的相反却使得问题很简单,他就是把位置作为区间段,结点值表示当前区间内满足要求的位置数,
    这里用到了离线处理的思想,将m个询问按照H值升序排列,这样的好处在于,后面的询问H不会因为前面更新的值产生影响,因为<=Hpre一定<=H
    巧妙地思路!
     
    BIT和ST代码,时间差不大多,空间自然BIT好点;
      1 /*树状数组*/
      2 #include<bits/stdc++.h>
      3 using namespace std;
      4 #define LL long long
      5 #define MAXN (100000+15)
      6 int C[MAXN];
      7 inline int lowbit(int x){return x&-x;}
      8 inline int sum(int x)
      9 {
     10     int ret=0;
     11     for(;x;x-=lowbit(x)) ret+=C[x];
     12     return ret;
     13 }
     14 inline void add(int x,int d,int n)
     15 {
     16     while(x<=n){
     17         C[x]+=d;
     18         x+=lowbit(x);
     19     }
     20 }
     21 struct node
     22 {
     23     int l,r,h,id,ans;
     24 }P[MAXN];
     25 bool cmpid(node A,node B){return A.id<B.id;}
     26 bool cnph(node A,node B){return A.h<B.h;}
     27 struct node2
     28 {
     29     int h,id;
     30     bool operator<(const node2& x)const{
     31     return h<x.h;}
     32 }Q[MAXN];
     33 int main()
     34 {
     35     int t,n,m,i,j,k=0,s;
     36     scanf("%d",&t);
     37     for(k=1;k<=t;++k)
     38     {
     39         memset(C,0,sizeof(C));
     40         scanf("%d%d",&n,&m);
     41         for(i=1;i<=n;++i) scanf("%d",&Q[i].h),Q[i].id=i;
     42         sort(Q+1,Q+1+n);
     43         for(i=1;i<=m;++i)
     44         {
     45             scanf("%d%d%d",&P[i].l,&P[i].r,&P[i].h);
     46             P[i].l++;
     47             P[i].r++;
     48             P[i].id=i;
     49         }
     50         printf("Case %d:
    ",k);
     51         sort(P+1,P+1+m,cnph);
     52         for(i=1,j=1;i<=m;++i)
     53         {
     54           while(j<=n&&Q[j].h<=P[i].h) add(Q[j++].id,1,n);
     55           P[i].ans=sum(P[i].r)-sum(P[i].l-1);
     56         }
     57         sort(P+1,P+1+m,cmpid);
     58         for(i=1;i<=m;++i)
     59         printf("%d
    ",P[i].ans);
     60     }
     61     return 0;
     62 }
     63 
     64 
     65 /* 线段树*/
     66 #include<bits/stdc++.h>
     67 using namespace std;
     68 #define MAXN 100000
     69 #define lc (id<<1)
     70 #define rc (id<<1|1)
     71 #define M ((L+R)>>1)
     72 int C[(MAXN<<2)+15];
     73 void update(int L,int R,int id,int x)
     74 {
     75   if(L==R){C[id]++;return;}
     76   if(x<=M) update(L,M,lc,x);
     77   else update(M+1,R,rc,x);
     78   C[id]=C[lc]+C[rc];
     79 }
     80 int query(int L,int R,int id,int l,int r)
     81 {
     82     if(L>=l&&R<=r){return C[id];}
     83     if(r<=M) return query(L,M,lc,l,r);
     84     else if(l>M) return query(M+1,R,rc,l,r);
     85     else return query(L,M,lc,l,r)+query(M+1,R,rc,l,r);
     86 }
     87 struct node
     88 {
     89     int l,r,h,id,ans;
     90 }P[MAXN+15];
     91 bool cmpid(node A,node B){return A.id<B.id;}
     92 bool cmph(node A,node B){return A.h<B.h;}
     93 struct node2
     94 {
     95     int h,id;
     96     bool operator<(const node2&x)const{return h<x.h;}
     97 }Q[MAXN+15];
     98 int main()
     99 {
    100     int t,i,j,n,m,k=0;
    101     scanf("%d",&t);
    102     for(k=1;k<=t;++k)
    103     {
    104         scanf("%d%d",&n,&m);
    105         for(i=1;i<=n;++i) scanf("%d",&Q[i].h),Q[i].id=i;
    106         sort(Q+1,Q+1+n);
    107         for(i=1;i<=m;++i)
    108         {
    109             scanf("%d%d%d",&P[i].l,&P[i].r,&P[i].h);
    110             P[i].l++;
    111             P[i].r++;
    112             P[i].id=i;
    113         }
    114         sort(P+1,P+1+m,cmph);
    115         for(i=1,j=1;i<=m;++i)
    116         {
    117             while(j<=n&&Q[j].h<=P[i].h){update(1,n,1,Q[j].id);j++;}
    118             P[i].ans=query(1,n,1,P[i].l,P[i].r);
    119         }
    120         sort(P+1,P+1+m,cmpid);
    121         printf("Case %d:
    ",k);
    122         for(i=1;i<=m;++i) printf("%d
    ",P[i].ans);
    123         memset(C,0,sizeof(C));
    124     }
    125     return 0;
    126 }
  • 相关阅读:
    [java]java String.split()函数的用法分析
    [sql]java.sql.Types的具体对应值(jdbcType)
    [sql]join的5种方式:inner join、left(outer) join、right (outer) Join、full(outer) join、cross join
    [java]String和Date、Timestamp之间的转换
    [Eclipse]保存java文件时,自动删除不需要的包import
    [postgresql]ROWS is not applicable when function does not return a set问题解决
    [postgreSql]postgreSql数据库、模式、表、函数的删除与创建
    zbb20170816 oracle Oracle 查看表空间、数据文件的大小及使用情况sql语句
    zbb20170811 mysql远程连接报错: Host * is not allowed to connect to this MySQL server,解决方法
    zbb20170811 linux 给用户授予文件夹权限
  • 原文地址:https://www.cnblogs.com/zzqc/p/7274216.html
Copyright © 2011-2022 走看看