zoukankan      html  css  js  c++  java
  • hdu4417(离线操作 + 树状数组)

    题意:

    给定一个长度为n的数组,有m次的查询,每次查询[a,b]区间里比H小的数有多少个?

    由于n和m的取值范围为0到10的5次方,所以直接回答会超时,所以考虑先读入所有的查询操作,然后依次回答比H小的[a,b]区间里的数有多少个,

    求和类似于求正序数的方法。

    写法可以边插变查,也可以边查边插,边查边插简单些;

    可是这道题从头wa到了尾,原因是add函数少打了等于号,扇自己一巴掌.

    边插边查:

    #include <iostream>
    #include <cstdio>
    #include <time.h>
    #include <stdlib.h>
    #include <cstring>
    #include<algorithm>
    #define maxn 110000
    #define LL  int
    using namespace std;
    struct node
    {
       LL value,id;
    };
    struct querynode
    {
        LL L,R,H=-1,cnt;
    };
    node a[maxn];
    querynode  que[maxn];
    LL c[maxn];
    LL N,M;
    LL ans[maxn];
    void init()
    {
       memset(a,0,sizeof(a));
       memset(c,0,sizeof(c));
       memset(ans,0,sizeof(ans));
    }
    
    bool cmp1(node a,node b)
       {
           return a.value<b.value;
       }
    bool cmp2(querynode a,querynode b)
    {
            return a.H<b.H;
    }
    int inline lowbit(int x){
        return x & (-x);
    }
    void inline add(int x){
        while(x <= N){
           c[x]++;
           x += lowbit(x);
        }
    }
    int inline sum(int x){
        int s = 0;
        while(x > 0){
          s += c[x];
          x -= lowbit(x);
        }
        return s;
    }
    
    void  solve()
    {
        int t=1;
        for(int i=1;i<=N;i++)
        {
                if(que[t].H==-1)
                {
                    break;
                }
                while(que[t].H<a[i].value && que[t].H!=-1)
                {
                    ans[ que[t].cnt ]=sum(que[t].R)-sum(que[t].L-1);
                    t++;
                }
                add(a[i].id);
                while(a[i].value==a[i+1].value && i<=N)
                {
                     i++;
                     add(a[i].id);
                }
                while(que[t].H==a[i].value && que[t].H!=-1)
                {
                    ans[ que[t].cnt ]=sum(que[t].R)-sum(que[t].L-1);
                    t++;
                }
        }
        for(int i=t;i<=M;i++)
        {
            ans[que[i].cnt]=sum(que[i].R)-sum(que[i].L-1);
        }
    }
    int main()
    {
        // freopen("test.txt","r",stdin);
        int t;
        scanf("%d",&t);
        int Case=1;
        for(int Case=1;Case<=t;Case++)
        {
          scanf("%d%d",&N,&M);
          init();
          for(int i=1;i<=N;i++)
          {
            scanf("%d",&a[i].value);
            a[i].id=i;
          }
          for(int i=1;i<=M;i++)
          {
             scanf("%d%d%d",&que[i].L,&que[i].R,&que[i].H);
             que[i].L++;
             que[i].R++;
             que[i].cnt=i;
          }
          sort(a+1,a+N+1,cmp1);
          sort(que+1,que+M+1,cmp2);
           solve();
           printf("Case %d:
    ",Case);
            for(int i = 1; i <= M; ++i){
              printf("%d
    ",ans[i]);
           }
        }
    
        return 0;
    }

    边查边插:

    #include <iostream>
    #include <cstdio>
    #include <time.h>
    #include <stdlib.h>
    #include <cstring>
    #include<algorithm>
    #define maxn 110000
    #define LL  int
    using namespace std;
    struct node
    {
       LL value,id;
    };
    struct querynode
    {
        LL L,R,H,cnt;
    };
    node a[maxn];
    querynode  que[maxn];
    LL c[maxn];
    LL N,M;
    LL ans[maxn];
    void init()
    {
       memset(a,0,sizeof(a));
       memset(c,0,sizeof(c));
       memset(ans,0,sizeof(ans));
       for(int i=0;i<maxn;i++)
       {
           que[i].H=-1;
       }
    }
    
    bool cmp1(node a,node b)
       {
           return a.value<b.value;
       }
    bool cmp2(querynode a,querynode b)
    {
            return a.H<b.H;
    }
    int inline lowbit(int x){
        return x & (-x);
    }
    void inline add(int x){
        while(x <= N ){
           c[x]++;
           x += lowbit(x);
        }
    }
    int inline sum(int x){
        int s = 0;
        while(x > 0){
          s += c[x];
          x -= lowbit(x);
        }
        return s;
    }
    
    void solve1()
    {
           for(int aski = 0,ditj = 0; aski < M; ++aski){
               while(ditj < N && que[aski].H >= a[ditj].value){
                  add(a[ditj].id);
                  ditj++;
               }
               ans[que[aski].cnt] = sum(que[aski].R) - sum(que[aski].L - 1);
           }
    }
    int main()
    {
         //freopen("test.txt","r",stdin);
        int t;
        scanf("%d",&t);
        int Case=1;
        for(int Case=1;Case<=t;Case++)
        {
          scanf("%d%d",&N,&M);
          init();
          for(int i=0;i<N;i++)
          {
            scanf("%d",&a[i].value);
            a[i].id=i+1;
          }
          for(int i=0;i<M;i++)
          {
             scanf("%d%d%d",&que[i].L,&que[i].R,&que[i].H);
             que[i].L++;
             que[i].R++;
             que[i].cnt=i+1;
          }
          sort(a,a+N,cmp1);
          sort(que,que+M,cmp2);
           solve1();
           printf("Case %d:
    ",Case);
            for(int i = 1; i <= M; ++i){
              printf("%d
    ",ans[i]);
           }
        }
    
        return 0;
    }
  • 相关阅读:
    Android开发环境搭建
    Noi 2016
    [二分图&最小割]
    [BZOJ 3145][Feyat cup 1.5]Str 解题报告
    [动态图]
    [组合数取模][中国剩余定理]
    [BZOJ 4436][Cerc2015]Kernel Knights
    [NOI 2014]做题记录
    [线段树合并]
    [树套树模板]
  • 原文地址:https://www.cnblogs.com/xianbin7/p/4786644.html
Copyright © 2011-2022 走看看