Sliding Window

这篇博客探讨了在解决滑动窗口问题时遇到的内存超限问题,指出使用ST表可能导致内存消耗过大,而线段树是更优的解决方案。同时,博主提到了在C++中,为提高IO效率,需要将ios_base::sync_with_stdio(false)和cin.tie(0)结合使用,但在此特定情况下,仍然无法通过测试,最终发现必须改用scanf和printf进行输入输出。
摘要由CSDN通过智能技术生成

Sliding Window
我一开始用ST表做的,超内存,这是ST表的一个弊端吧?太耗内存
ST表

#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <stack>
#include <queue>
using namespace std;
#define mod 1e9+7

#define inf 0x3f3f3f3f
const double PI = atan(1.0)*4.0;
typedef long long ll;
const int N=1e6+5;
int lg[N],logN=20;
int dp[N][20],pd[N][20],a[N];
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    //freopen("E:\\in.txt","r",stdin);
    int n,k;
    cin>>n>>k;
    for(int i=1; i<=n; i++)
        cin>>a[i];

    lg[0]=-1;
    for(int i=1; i<=N; i++)
        lg[i]=lg[i>>1]+1;
    for(int i=1; i<=n; i++)
    {
        dp[i][0]=a[i];
        pd[i][0]=a[i];
    }
    for(int j=1;j<=25;j++)
    {
        for(int i=1; i+(1<<j)-1<=n; i++)
        {
            dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
            pd[i][j]=min(pd[i][j-1],pd[i+(1<<(j-1))][j-1]);
        }
    }
    int m=lg[k];
    //cout<<"m: "<<m<<endl;
     for(int i=1; i+k-1<=n; i++)
    {

        int mi=min(pd[i][m],pd[i+k-1-(1<<m)+1][m]);
        cout<<mi<<" ";

    }
    cout<<endl;
    for(int i=1; i+k-1<=n; i++)
    {

        int ma=max(dp[i][m],dp[i+k-1-(1<<m)+1][m]);
        cout<<ma<<" ";

    }






}

正确做法是线段树,但是时间勉强能过
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);过不了
必须改成scanf输入printf输出才行

#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <stack>
#include <queue>
using namespace std;
#define mod 1e9+7
#define inf 0x3f3f3f3f
const double PI = atan(1.0)*4.0;
typedef long long ll;
const int N=1e6+5;

struct tree
{
    int l,r,mi,ma;
}b[4*N];
int a[N];
void build(int now,int l,int r)
{
    b[now].l=l;
    b[now].r=r;
    if(l==r)
    {
        b[now].mi=b[now].ma=a[l];
        return;

    }
    int mid=(l+r)>>1;
    build(2*now,l,mid);
    build(2*now+1,mid+1,r);
    b[now].ma=max(b[2*now].ma,b[2*now+1].ma);
    b[now].mi=min(b[2*now].mi,b[2*now+1].mi);
}
int searchma(int now,int l,int r)
{if(b[now].l==l&&b[now].r==r)return b[now].ma;
   int mid=(b[now].l+b[now].r)>>1;
    if(mid>=r) return searchma(2*now,l,r);
    else if(mid<l)return searchma(2*now+1,l,r);
    else
    return max(searchma(now*2,l,mid),searchma(now*2+1,mid+1,r));


}
int searchmi(int now,int l,int r)
{
    if(b[now].l==l&&b[now].r==r)return b[now].mi;
    int mid=(b[now].l+b[now].r)>>1;
    if(mid>=r) return searchmi(2*now,l,r);
    else if(mid<l)return searchmi(2*now+1,l,r);
    else
    return min(searchmi(now*2,l,mid),searchmi(now*2+1,mid+1,r));

}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
   // freopen("E:\\in.txt","r",stdin);

    int n,k,x;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
    scanf("%d",&a[i]);
    build(1,1,n);
    for(int i=1;i+k-1<=n;i++)
    {
        int x=searchmi(1,i,i+k-1);
        printf("%d ",x);

    }
       printf("\n");

    for(int i=1;i+k-1<=n;i++)
    {
        int x=searchma(1,i,i+k-1);
         printf("%d ",x);

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值