Loading...

滑动窗口 洛谷P1886题解

check评论:0 条 remove_red_eye浏览量:467 change_historyTags:编程学习笔记
作者 : deco date_range日期 : 2018-05-09

这道题我拿的裸的线段树做的

思路就是建两个线段树,一个最大树 ,一个最小树

最后依次查询即可

但是,这样是肯定TLE哒,qwq

TLE代码:

#include <iostream>
#include <stdio.h>
#define pushup_min(o) sum1[o]=min(sum1[o<<1],sum1[o<<1|1])
#define pushup_max(o) sum2[o]=max(sum2[o<<1],sum2[o<<1|1])
using namespace std;
int sum1[4000004],sum2[4000004],a[1000001],n,k;
void build_min(int o,int lf,int rg)//构建最小树
{
    if(lf==rg)
    {
        sum1[o]=a[lf];
        return ;
    }
    int mid=(lf+rg)>>1;
    build_min(o<<1,lf,mid);
    build_min(o<<1|1,mid+1,rg);
    pushup_min(o);
}
void build_max(int o,int lf,int rg)//构建最大树
{
    if(lf==rg)
    {
        sum2[o]=a[lf];
        return ;
    }
    int mid=(lf+rg)>>1;
    build_max(o<<1,lf,mid);
    build_max(o<<1|1,mid+1,rg);
    pushup_max(o);
}
int query_min(int o,int lf,int rg,int l,int r)//查询最小值
{
    if(l<=lf&&rg<=r)
    {
        return sum1[o];
    }
    int mid=(lf+rg)>>1;
    int ans=0x3f3f3f3f;
    if(l<=mid)
    {
        ans=min(ans,query_min(o<<1,lf,mid,l,r));
    }
    if(mid<r)
    {
        ans=min(ans,query_min(o<<1|1,mid+1,rg,l,r));
    }
    return ans;
}
int query_max(int o,int lf,int rg,int l,int r)//查询最大值
{
    if(l<=lf&&rg<=r)
    {
        return sum2[o];
    }
    int mid=(lf+rg)>>1;
    int ans=-0x3f3f3f3f;
    if(l<=mid)
    {
        ans=max(ans,query_max(o<<1,lf,mid,l,r));
    }
    if(mid<r)
    {
        ans=max(ans,query_max(o<<1|1,mid+1,rg,l,r));
    }
    return ans;
}
int main()
{
    cin>>n>>k; 
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    build_min(1,1,n);
    build_max(1,1,n);
    for(int i=1;i<=(n-k+1);i++)//顺次查询
    {
        printf("%d ",query_min(1,1,n,i,(i+k-1)));
    }
    printf("\n");
    for(int i=1;i<=(n-k+1);i++)
    {
        printf("%d ",query_max(1,1,n,i,(i+k-1)));
    }
}

但是我不想超时啊qwq
加入优化

// 以下是大量玄学优化
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#include <iostream>
#include <stdio.h>
#define pushup_min(o) sum1[o]=min(sum1[o<<1],sum1[o<<1|1])
#define pushup_max(o) sum2[o]=max(sum2[o<<1],sum2[o<<1|1])
using namespace std;
int sum1[4000004],sum2[4000004],a[1000001],n,k;
void build_min(int o,int lf,int rg)//构建最小树
{
    if(lf==rg)
    {
        sum1[o]=a[lf];
        return ;
    }
    int mid=(lf+rg)>>1;
    build_min(o<<1,lf,mid);
    build_min(o<<1|1,mid+1,rg);
    pushup_min(o);
}
void build_max(int o,int lf,int rg)//构建最大树
{
    if(lf==rg)
    {
        sum2[o]=a[lf];
        return ;
    }
    int mid=(lf+rg)>>1;
    build_max(o<<1,lf,mid);
    build_max(o<<1|1,mid+1,rg);
    pushup_max(o);
}
int query_min(int o,int lf,int rg,int l,int r)//查询最小值
{
    if(l<=lf&&rg<=r)
    {
        return sum1[o];
    }
    int mid=(lf+rg)>>1;
    int ans=0x3f3f3f3f;
    if(l<=mid)
    {
        ans=min(ans,query_min(o<<1,lf,mid,l,r));
    }
    if(mid<r)
    {
        ans=min(ans,query_min(o<<1|1,mid+1,rg,l,r));
    }
    return ans;
}
int query_max(int o,int lf,int rg,int l,int r)//查询最大值
{
    if(l<=lf&&rg<=r)
    {
        return sum2[o];
    }
    int mid=(lf+rg)>>1;
    int ans=-0x3f3f3f3f;
    if(l<=mid)
    {
        ans=max(ans,query_max(o<<1,lf,mid,l,r));
    }
    if(mid<r)
    {
        ans=max(ans,query_max(o<<1|1,mid+1,rg,l,r));
    }
    return ans;
}
int main()
{
    cin>>n>>k; 
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    build_min(1,1,n);
    build_max(1,1,n);
    for(int i=1;i<=(n-k+1);i++)//顺次查询
    {
        printf("%d ",query_min(1,1,n,i,(i+k-1)));
    }
    printf("\n");
    for(int i=1;i<=(n-k+1);i++)
    {
        printf("%d ",query_max(1,1,n,i,(i+k-1)));
    }
}

qwq

暂无评论

正在回复给  
去登陆?

   点击刷新验证码

标签云

文章留名