• 【t019】window(线段树做法)


    Time Limit: 2 second
    Memory Limit: 256 MB

    【问题描述】

    给你一个长度为N 的数组,一个长为K的滑动的窗体从最左移至最右端,你只能见到窗口的K个数,每次窗体向右移动一位,如下表:
    

    Window position Min value Max value
    [1 3 -1] -3 5 3 6 7 -1 3
    1 [3 -1 -3] 5 3 6 7 -3 3
    1 3 [-1 -3 5] 3 6 7 -3 5
    1 3 -1 [-3 5 3] 6 7 -3 5
    1 3 -1 -3 [5 3 6] 7 3 6
    1 3 -1 -3 5 [3 6 7] 3 7

    你的任务是找出窗口在各位置时的Max value和Min value。
    

    【输入格式】

    第一行N,K,第二行为长度为N的数组
    

    【输出格式】

    第一行每个位置的Min value,第二行每个位置的Max value
    

    【输入样例1】

    8 3
    
    1 3 -1 -3 5 3 6 7
    

    【输出样例1】

    -1 -3 -3 -3 3 3
    
    3 3 5 5 6 7
    

    数据规模

    20%:N≤500;50%:N≤100000;100%:N≤1000000;
    

    【题目链接】:http://noi.qz5z.com/viewtask.asp?id=t019

    【题解】

    线段树(开到3s才过)

    【完整代码】

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    
    const int MAXN = 1e6+100;
    
    int ma[MAXN<<2],mi[MAXN<<2];
    int n,k,a[MAXN];
    
    void build(int l,int r,int rt)
    {
        if (l==r)
        {
            ma[rt] = mi[rt] = a[l];
            return;
        }
        int m = (l+r)>>1;
        build(lson);
        build(rson);
        ma[rt] = max(ma[rt<<1],ma[rt<<1|1]);
        mi[rt] = min(mi[rt<<1],mi[rt<<1|1]);
    }
    
    int findma(int L,int R,int l,int r,int rt)
    {
        if (L <= l && r <= R)
            return ma[rt];
        int m = (l+r)>>1;
        int temp1 = -21e8,temp2 = -21e8;
        if (L <= m)
            temp1 = findma(L,R,lson);
        if (m < R)
            temp2 = findma(L,R,rson);
        return max(temp1,temp2);
    }
    
    int findmi(int L,int R,int l,int r,int rt)
    {
        if (L <= l && r <= R)
            return mi[rt];
        int m = (l+r)>>1;
        int temp1 = 21e8,temp2 = 21e8;
        if (L <= m)
            temp1 = findmi(L,R,lson);
        if (m < R)
            temp2 = findmi(L,R,rson);
        return min(temp1,temp2);
    }
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        scanf("%d%d",&n,&k);
        for (int i = 1;i <= n;i++)
            scanf("%d",&a[i]);
        build(1,n,1);
        for (int r = k;r <= n;r++)
        {
            int l = r-k+1;
            printf("%d",findmi(l,r,1,n,1));
            if (r==n)
                puts("");
            else
                putchar(' ');
        }
        for (int r = k;r <= n;r++)
        {
            int l = r-k+1;
            printf("%d",findma(l,r,1,n,1));
            if (r==n)
                puts("");
            else
                putchar(' ');
        }
        return 0;
    }
    
  • 相关阅读:
    vlc音视频开发(二)环境搭建(VS篇)
    vlc音视频开发(一)环境搭建(qt篇)
    Qt国际化
    Qt解析王者荣耀英雄JSON文件
    Qt使用spdlog日志
    windows核心编程之多进程多线程,线程的同步互斥
    第十八关——写在最后
    第十七关——搜索优化
    第十六关——动态规划
    第十五关——网络流
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626668.html
Copyright © 2020-2023  润新知