HDU 4417 Super Mario (树状数组)

来源:互联网 发布:好易网络手机电视直播 编辑:程序博客网 时间:2024/06/06 01:26

思路:

  1. 首先我们先回顾一下树状数组。树状数组的的直接目的即区间求和(logn)。但由于具有logn单点修改的功能使得区间求和更为方便。
  2. 对于这道题来说,我们先对m个询问中的h升序排序,利用了<=h1的元素一定也<=h2这个递推式,然后将n个数也排序,但同时需要记录这些数原本的位置信息。
  3. 对于每个询问,我们将符合hi条件的点加入树状数组,注意,我们是将这个点原来的位置加入树状数组(数量是1)。这样构造出来的数组即是满足当前所有点<=hi的情况下,getsum_tree[i]得到的即是小于等于位置i的满足条件的点的个数。
  4. 对于某个区间i,j来说,getsum_tree[j] - getsum_tree[i]。注意根据实际情况讨论边界。

代码:

#include <iostream>#include <cstdio>#include <algorithm>#include <string.h>using namespace std;int n,m;int c[100010];struct san{    int val,p;    san(){}    san(int vv,int i){val = vv,p = i;}}lisan[100010];struct node1{    int l,r,h,num;    node1(){}    node1(int ll,int rr,int hh,int numm){        l = ll,r = rr, h = hh, num = numm;    }}query[100010];void insert(int i,int x){    while(i <= n){        c[i] += x;        i += (i&-i);    }}int getsum(int i){    int sum = 0;    while(i > 0){        sum += c[i];        i -= (i&-i);    }    return sum;}int ans[100010];bool cmp(const san&a, const san&b){return a.val<b.val;}bool cmp2(const node1&a, const node1&b){return a.h<b.h;}int main(){    int t;    cin>>t;    int nca = 0;    while(t--){        memset(c,0,sizeof(c));        memset(lisan,0,sizeof(lisan));        nca++;        scanf("%d%d",&n,&m);        int temp;        for(int i = 1;i <= n;i++){            scanf("%d",&temp);            lisan[i] = san(temp,i);        }        for(int i = 1;i <= m;i++){            scanf("%d%d%d",&query[i].l,&query[i].r,&query[i].h);            query[i].num = i;        }        sort(lisan+1,lisan+1+n,cmp);        sort(query+1,query+1+m,cmp2);        int now = 1;        for(int i = 1;i <= n;i++){            if(lisan[i].val <= query[now].h){                insert(lisan[i].p,1);            }            else if(now <= m-1){                ans[query[now].num] = getsum(query[now].r+1) - getsum(query[now].l) ;                now++;                i--;            }            else break;        }        for(int i = now;i <= m;i++){            ans[query[i].num] = getsum(query[i].r+1) - getsum(query[i].l);        }        printf("Case %d:\n",nca);        for(int i = 1;i <= m;i++){            printf("%d\n",ans[i]);        }    }    return 0;}
0 1
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 哪些人不宜使用香砂和胃丸 哪些人不适合用木香顺气丸 补脾益肠丸不适合什么人吃 龙胆泄肝丸不适用那些人 什么人不能吃五子洐宗丸 大活络丸哪些人不能吃 骨化三醇胶丸适合适合什么人 什么人不宜吃麝香保心丸 天王补心丸不适合什么人吃 人参保肺丸 香砂养胃丸不适合什么人吃 香砂六君子丸不适合哪些人 补脾益肠丸适合什么人吃 藿香正气丸什么人不能吃 安神补心丸适合哪些人吃 什么人不适合吃柏子养心丸 木香顺气丸不适合哪些人吃 泰国蜈蚣丸哪些人禁用 小活络丸哪些人不能用 2陈丸哪种人不能吃 大补阴丸适合什么人吃 黑芝麻丸不适合什么人吃 清心丸适合什么人吃 安宫丸什么人不能吃 兰丸多人上受 舒肝健胃丸不适合什么人吃 丹栀逍遥丸适合哪些人 人丹 什么人不适合吃红毛丹 哪些人不适合吃香丹清 丹叁粉哪种人不能吃 丹栀逍遥丸什么人不能吃 百消丹不适用于什么人 哪些人不能吃摩罗丹 环阳丹医生江涛是何许人 丹人修仙之仙界篇 全家人的丹尼斯供应商 全家人的丹尼斯大卖场供应商 艳鼎丹仙 那时那人 什么人不能吃天王补心丹 大活络丹不适合什么人