zoukankan      html  css  js  c++  java
  • POJ 3264 线段树入门解题报告

    题意:给n个值, Q次询问, 每次询问给定一个区间, 要求输出该区间最大最小值之差

    思路:暴力的话每次询问都要遍历多次for循环一定会超时, 用线段树记录区间的信息(左边界右边界, 该区间最大值最小值)

    代码:

     1 #include<stdio.h>
     2 #include<algorithm>
     3 #define inf 0x3f3f3f3f
     4 using namespace std;
     5 
     6 int n, m, arr[50010];
     7 int ansmax, ansmin;
     8 
     9 struct Tree
    10 {
    11     int maxx, minn, left, right; //记录区间信息 
    12 }tree[50010 * 4]; //开四倍空间 
    13 
    14 void build(int left, int right, int k)
    15 {
    16     tree[k].left = left, tree[k].right = right; //区间左右 
    17     if(tree[k].left == tree[k].right)
    18     {
    19         tree[k].maxx = tree[k].minn = arr[left]; //分到最后只剩下一个值 记为最大最小值 
    20         return ;
    21     }
    22     int mid = (left + right)/2;
    23     build(left, mid, k * 2); //往左右儿子构造线段树 
    24     build(mid + 1, right, k * 2 + 1);
    25     tree[k].maxx = max(tree[k * 2].maxx, tree[k * 2 + 1].maxx); //满足区间相加.子区间之间的最大最小值也是父亲区间的最大最小值 
    26     tree[k].minn = min(tree[k * 2].minn, tree[k * 2 + 1].minn);
    27 }
    28 
    29 void query(int k, int left, int right, int find_left, int find_right)
    30 {  //如果ansmax已经大于等于该点区间最大值,ansmin已经小于等于该点区间最小值 , 不用更新,return  
    31     if(ansmax >= tree[k].maxx && ansmin <= tree[k].minn)
    32         return ;
    33     if(find_left == left && find_right == right)
    34     {  //查询区间刚好是某个节点的区间, 该区间已经记录了最大最小值信息,可以直接调用并return  
    35         ansmax = max(ansmax, tree[k].maxx);
    36         ansmin = min(ansmin, tree[k].minn);
    37         return ;
    38     }
    39     int mid = (left + right)/2;
    40     if(find_right <= mid) //查询区间全位于该节点的左儿子区间 
    41         query(2 * k, left, mid, find_left, find_right);
    42     else if(find_left > mid)//查询区间全位于该节点的右儿子区间 
    43         query(2 * k + 1, mid + 1, right, find_left, find_right);
    44     else
    45     {  //有位于左儿子和右儿子部分 
    46         query(2 * k, left, mid, find_left, mid);
    47         query(2 * k + 1, mid + 1, right, mid + 1, find_right);
    48     }    
    49 }
    50 
    51 int main()
    52 {
    53     int a, b;
    54     scanf("%d%d", &n, &m);
    55     for(int i = 1; i <= n; i ++)//线段树根节点从1开始 ,数组从1开始存 
    56         scanf("%d", &arr[i]);
    57     build(1, n, 1);
    58     for(int i = 1; i <= m; i ++)
    59     {
    60         ansmax = -inf;
    61         ansmin = inf;
    62         scanf("%d%d", &a, &b);
    63         query(1, 1, n, a, b);
    64         printf("%d\n", ansmax - ansmin);
    65     }
    66     return 0;
    67 }
  • 相关阅读:
    [原]C++ double 小数精度控制
    C++ double 小数精度控制
    从微软小冰看微软运营手段的转型
    Windows下搭建FTP服务器
    C++ 下使用curl 获取ftp文件
    解决MSF更新证书错误
    mimikaz获取明文密码
    metasploit5配置数据库
    Cobalt Strike几种不常见的上线方式
    Powershell
  • 原文地址:https://www.cnblogs.com/yuanweidao/p/10490567.html
Copyright © 2011-2022 走看看