zoukankan      html  css  js  c++  java
  • 线段树(two value)与树状数组(RMQ算法st表)

    士兵杀敌(三)

    时间限制:2000 ms  |  内存限制:65535 KB
    难度:5
    描述

    南将军统率着N个士兵,士兵分别编号为1~N,南将军经常爱拿某一段编号内杀敌数最高的人与杀敌数最低的人进行比较,计算出两个人的杀敌数差值,用这种方法一方面能鼓舞杀敌数高的人,另一方面也算是批评杀敌数低的人,起到了很好的效果。

    所以,南将军经常问军师小工第i号士兵到第j号士兵中,杀敌数最高的人与杀敌数最低的人之间军功差值是多少。

    现在,请你写一个程序,帮小工回答南将军每次的询问吧。

    注意,南将军可能询问很多次。

    输入
    只有一组测试数据
    第一行是两个整数N,Q,其中N表示士兵的总数。Q表示南将军询问的次数。(1<N<=100000,1<Q<=1000000)
    随后的一行有N个整数Vi(0<=Vi<100000000),分别表示每个人的杀敌数。
    再之后的Q行,每行有两个正正数m,n,表示南将军询问的是第m号士兵到第n号士兵。
    输出
    对于每次询问,输出第m号士兵到第n号士兵之间所有士兵杀敌数的最大值与最小值的差。
    样例输入
    5 2
    1 2 6 9 3
    1 2
    2 4
    样例输出
    1
    7
    题解:线段树;还可以用RMQ算法,感觉挺复杂,也没看。。。还有宏定义最好大写。。。。。

    思路:线段树叶子节点存两个值:最大和最小值

    #include <iostream>
    #include <iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include <stdio.h>
    #include <string.h>
    #define rep(i , n) for(int i = 0 ; i < (n) ; i++)
    using namespace std;
    const int N = 100009 ;
    const int INF=0x3f3f3f3f;
    long long ans = 0 , flag = 1;
    long long a[200009] ,  sum1[200009] , sum2[200009];
    long long max1 = -INF , min1 = INF;
    struct Node{
        long long l , r , mi , ma ;
    }tree[N*4];
    
    void build(long long l , long long r , int root)
    {
        tree[root].l = l , tree[root].r = r ;
        if(l == r)
        {
            scanf("%lld" ,&tree[root].mi);
            tree[root].ma = tree[root].mi ;
            return ;
        }
        long long mid = (l + r) >> 1;
        if(l <= mid)
            build(l , mid , root*2);
        if(r > mid)
            build(mid+1 , r , root*2+1);
        tree[root].mi = min(tree[root*2].mi , tree[root*2+1].mi);
        tree[root].ma = max(tree[root*2].ma , tree[root*2+1].ma);
        cout << tree[root].ma << " " << tree[root].mi << endl ;
    }
    
    void query(long long l , long long r , int root)
    {
        if(tree[root].l >= l && tree[root].r <= r)
        {
            cout << tree[root].ma <<" " << tree[root].mi <<endl ;
            max1 = max(max1 , tree[root].ma) ;
            min1 = min(min1 , tree[root].mi) ;
            return ;
        }
        long long mid = (tree[root].l + tree[root].r) >> 1 ;
        if(l <= mid)
            query(l , r , root*2);
        if(r > mid)
            query(l , r, root*2+1);
    }
    
    int main()
    {
    
        int n , q ;
        while(~scanf("%d%d" , &n , &q))
        {
            build(1 , n , 1);
            for(int i = 0 ; i < q ; i++)
            {
                long long l , r ;
                scanf("%lld%lld" , &l ,&r);
                query(l , r , 1);
                cout << max1 - min1 << endl ;
                max1 = -INF , min1 = INF ; // 不能赋值为零噢。
            }
        }
    
    
    
        return 0;
    }

     RMQ(算法)st表排序

    https://blog.csdn.net/niushuai666/article/details/6624672

    #include <iostream>
    #include <iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include <stdio.h>
    #include <math.h>
    #include <string.h>
    #define rep(i , n) for(int i = 0 ; i < (n) ; i++)
    using namespace std;
    const int N = 10009 ;
    const int INF=0x3f3f3f3f;
    long long ans = 0 , flag = 1;
    long long max1 = -INF , min1 = INF;
    int a[N] , dpa[N][N]  , dpb[N][N];
    int n , q ;
    
    void RMQ() { for(int j = 1 ; j < 20 ; j++) { for(int i = 1 ; i <= n ; i++) { if(i + (1 << j) - 1 <= n) { dpa[i][j] = max(dpa[i][j-1] , dpa[i + (1 << j - 1)][j-1]);//状态转移方程 dpb[i][j] = min(dpb[i][j-1] , dpb[i+ (1 << j - 1)][j-1]); } } } } int main() { while(~scanf("%d%d" , &n , &q)) { for(int i = 1 ; i <= n ; i++) { scanf("%d" , &a[i]); dpa[i][0] = dpb[i][0] = a[i];//赋初值 } RMQ(); for(int i = 0 ; i < q ; i++) { long long l , r ; scanf("%lld%lld" , &l ,&r); int k = (int)(log(r - l + 1) / log(2.0)) ; int max1 = max(dpa[l][k] , dpa[r-(1 << k) + 1][k]);//查表 int min1 = min(dpb[l][k] , dpb[r -(1 << k) + 1][k]); printf("%d " , max1 - min1); } } return 0; }
  • 相关阅读:
    python autopep8
    安卓代码覆盖率:android studio+ gradle+jacoco
    mac上运行appium提示错误Encountered internal error running command 解决办法
    python ide ---wing 注册机
    python 自动发邮件 Errno61 Connection refused
    instruments usage error specified target process is invalid
    selenium 关于富文本的处理
    动态规划计算字符相似度感觉棒棒哒
    windbg不识别pdb文件符号
    正则匹配全部中文
  • 原文地址:https://www.cnblogs.com/nonames/p/11274899.html
Copyright © 2011-2022 走看看