• 士兵杀敌(三)


    题目描述

    解决方案一:用线段树解决,因为查询的是某区间的最值

    时间1396   空间  5304  代码长度75
    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    using namespace std;
    struct node
    {
        int l,r,min,max;
    };
    const int N=100005;
    int num[N];
    #define L(x) (x<<1)
    #define R(x) ((x<<1)+1)
    #define M(x,y) ((x+y)>>1)
    node tree[4*N];
    int big,small;
    //建立线段树,由于是某个区间并未涉及到单个点,我建立的是叶子节点区间长度为1,而不是到单个点的线段树
    
    void build(int t,int l,int r)
    {
        tree[t].l=l;
        tree[t].r=r;
        if(l+1==r)
        {
            if(num[l]>num[r]){tree[t].min=num[r];tree[t].max=num[l];}
            else {tree[t].min=num[l];tree[t].max=num[r];}
            return;
        } 
        int mid=M(l,r);
        build(L(t),l,mid);
        build(R(t),mid,r);
        tree[t].max=max(tree[L(t)].max,tree[R(t)].max);
        tree[t].min=min(tree[L(t)].min,tree[R(t)].min);
    }
    //查询操作很简单,看看这个区间的最大最小值就行了
    void query(int t,int l,int r)
    {
        if(tree[t].l>=l && tree[t].r<=r)
        {
            if(tree[t].max>big)big=tree[t].max;
            if(tree[t].min<small)small=tree[t].min;
            return;
        }
        int mid=M(tree[t].l,tree[t].r);
        if(r<=mid)query(L(t),l,r);
        else if(l>=mid)query(R(t),l,r);
        else 
        {
            query(L(t),l,mid);
            query(R(t),mid,r);
        }
    }
    
    int main()
    {
        int i,n,q;
        scanf("%d%d",&n,&q);
        for(i=1;i<=n;i++)scanf("%d",num+i);
        build(1,1,n);
        int a,b;
        while(q--)
        {
            scanf("%d%d",&a,&b);
            big=-1,small=100000005;
          //考虑问题要全面,当a==b时,线段树是不适应的,因为我建立的线段树是[a,b],[b,c],应该列出来单独考虑,在这个地方两次没提交成功
            if(a==b)printf("0\n");,
            else
            {
               query(1,a,b);
              printf("%d\n",big-small);
             }
        }
       system("pause");
        return 0;
    }
    
     
     解决方案二:rmq的st算法即sparse table
    时间  904    空间:15852
     45行
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    #include <cstdio>
    using namespace std;
    const int N=100000;
    
    int stmax[N][20],stmin[N][20],d[20];
    
    void init(int n)
    {
        int i,j;
        d[0]=1;
        for(i=1;i<=20;i++)d[i]=d[i-1]<<1;
        for(i=1;i<=n;i++){
            scanf("%d",&stmax[i][0]);
            stmin[i][0]=stmax[i][0];
        }
        int len = int(log(n*1.0)/log(2.0));
        for(j=1;j<=len;j++)
          for(i=1;i<=n;i++)
          if(i+d[j]-1<=n)
          {
                stmax[i][j]=max(stmax[i][j-1],stmax[i+d[j-1]][j-1]);
                stmin[i][j]=min(stmin[i][j-1],stmin[i+d[j-1]][j-1]);
          }
    }
    void rmq(int q) //
    {
        int x,y,len;
        while(q--)
        {
            scanf("%d%d",&x,&y);
            len=int(log(y-x+1.0)/log(2.0)); 
            printf("%d\n",max(stmax[x][len],stmax[y-d[len]+1][len]));
            printf("%d\n",min(stmin[x][len],stmin[y-d[len]+1][len]));
        }
    }
    int main(){
          int n, q;
          scanf("%d%d",&n,&q);
          init(n);
          rmq(q);      
        
       system("pause");
        return 0;
    }
    

     

    15852   代码长度:45行

  • 相关阅读:
    C# 编码解码
    asp.net跨域问题
    C# crc16modbus
    c# 日志生成
    C# 对newtonsoft.json对象进行ascii排序
    C# 字节转结构体、结构体转字节
    按ascill排序参数
    C# Rsa加密(私钥加密、公钥解密、密钥格式转换、支持超大长度分段加密)
    Interview
    Leetcode
  • 原文地址:https://www.cnblogs.com/hpustudent/p/2129525.html
Copyright © 2020-2023  润新知