蒟蒻求助SOS

P1886 滑动窗口 /【模板】单调队列

HOIer_9_42 @ 2019-10-05 12:05:34

有路过的大佬可以帮我看一下怎么用

O(n log n)的算法A了这道题吗?

这个程序无论怎么调数组大小不是RE就是MLE(可能一定是因为我太菜了)

代码如下——

#pragma GCC optimize(3)
#pragma GCC optimize("inline")
#pragma once
#include<bits/stdc++.h>
#define q register
#define qsize 1<<21
#define INF 1<<31-1

typedef long long ll;

using namespace std;

struct Node {
    ll in;
    ll ax;
    ll le;
    ll ri;
} tr[qsize<<2];

ll n,m,a[qsize],ans_min,ans_max,flo,cel;

inline ll qread()
{
    q char ch=getchar();
    q ll v=0,sign=1;
    while(ch<'0'||ch>'9') {
        if(ch=='-')   sign=-1;
           ch=getchar();
    }
    while(ch>='0'&&ch<='9') {
        v=v*10+ch-'0';
           ch=getchar();
    }
    return v*sign;
}

inline void qwrite(ll v)
{
    if(v<0) {
        v=-v;
           putchar('-');
    }
    if(v>9)   qwrite(v/10);
       putchar(v%10+'0');
}

inline ll Max(ll x,ll y)
{
    return x>y?x:y;
}

inline ll Min(ll x,ll y)
{
    return x<y?x:y;
}

inline void Build(ll p,ll l,ll r)
{
    ll mid=l+r>>1;
    if(l>r)   return ;
    if(l==r) {
        tr[p].le=l,tr[p].ri=r;
        tr[p].in=tr[p].ax=a[l];
           return ;
    }
    Build(p<<1,l,mid);
    Build(p<<1|1,mid+1,r);
    tr[p].in=Min(tr[p<<1].in,tr[p<<1|1].in);
    tr[p].ax=Max(tr[p<<1].ax,tr[p<<1|1].ax);
}

inline ll Query_x(ll p,ll l,ll r) // x -----> xiao(小)
{
    ll res=INF,mid=l+r>>1;
    if(l>r)   return 0;  
    if(flo<=l&&r<=cel) {
        return tr[p].in;
    }
    if(flo<=mid)   res=Query_x(p<<1,l,mid);
    if(cel>mid)    res=Min(res,Query_x(p<<1|1,mid+1,r));
    return res;
}

inline ll Query_d(ll p,ll l,ll r) // d -----> da(大)
{
    ll res=-INF,mid=l+r>>1;
    if(l>r)   return 0;
    if(flo<=l&&r<=cel) {
        return tr[p].ax;
    }
    if(flo<=mid)   res=Query_d(p<<1,l,mid);
    if(cel>mid)    res=Max(res,Query_d(p<<1|1,mid+1,r));
    return res;
}

int main()
{
    n=qread();
    m=qread();
    ll tag=qsize<<2;
    for(q ll i=1;(i-1)^tag;i++) {
        tr[i].in=INF;
        tr[i].ax=-INF;
    }
    for(q ll i=1;(i-1)^n;i++)   a[i]=qread();
    Build(1,1,n);
    for(q ll i=m;(i-1)^n;i++) {
        flo=i-m+1,cel=i;
        ans_min=Query_x(1,1,n);
        qwrite(ans_min),putchar(' ');
    }
    putchar('\n');
    for(q ll i=m;(i-1)^n;i++) {
        flo=i-m+1,cel=i;
        ans_max=Query_d(1,1,n);
        qwrite(ans_max),putchar(' ');
    }
    putchar('\n');
    return 0;
}

by 7KByte @ 2019-10-05 12:08:07

本题单调队列,O(NlogN)被卡


by zhy137036 @ 2019-10-05 12:08:33

单调队列不就完了,还用线段树?


by zhy137036 @ 2019-10-05 12:09:26

@Inf_Voltage 然而他并没有T


by zhy137036 @ 2019-10-05 12:12:01

@HOIer_9_42 根据我的计算,你的数组144MB,再加上递归的栈,肯定得M


by zhy137036 @ 2019-10-05 12:14:49

等等,刚才算错了(把<<2当成*2了),应该是208MB


by HOIer_9_42 @ 2019-10-05 14:17:09

但是这道题线段树做法似乎也能A啊


by ⚡小林孑⚡ @ 2019-10-05 15:18:20

@HOIer_9_42 线段树RMQ是可以A的·


|