线段树求助

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

youyi2008 @ 2022-07-26 16:16:13

#include<iostream>
using namespace std;

const int N=1e6+1;
int n,k;
int a[N];
namespace Max{
struct node
{
    int l,r;
    int v;
}tr[N*4];

void pushup(int x)
{
    tr[x].v=max(tr[x<<1].v,tr[x<<1|1].v);
}

void build(int u,int l,int r)
{
    tr[u].l=l,tr[u].r=r;
    if(l==r)
    {
        tr[u].v=a[l];
        return;
    }
    int mid=l+r>>1;
    build(u<<1,l,mid),build(u<<1|1,mid+1,r);
    pushup(u);
}

int query(int u,int l,int r)
{
    if(tr[u].l>=l&&tr[u].r<=r)  
        return tr[u].v;
    int mid=l+r>>2;
    int v=-0x3f3f3f3f;
    if(tr[u<<1].r>=l)
        v=query(u<<1,l,r);
    if(tr[u<<1|1].l<=r)
        v=max(v,query(u<<1|1,l,r));
    return v;
}
}
namespace Min{
struct node
{
    int l,r;
    int v;
}tr[N*4];

void pushup(int x)
{
    tr[x].v=min(tr[x<<1].v,tr[x<<1|1].v);
}

void build(int u,int l,int r)
{
    tr[u].l=l,tr[u].r=r;
    if(l==r)
    {
        tr[u].v=a[l];
        return;
    }
    int mid=l+r>>1;
    build(u<<1,l,mid),build(u<<1|1,mid+1,r);
    pushup(u);
}

int query(int u,int l,int r)
{
    if(tr[u].l>=l&&tr[u].r<=r)  
        return tr[u].v;
    int mid=l+r>>2;
    int v=0x3f3f3f3f;
    if(tr[u<<1].r>=l)
        v=query(u<<1,l,r);
    if(tr[u<<1|1].l<=r)
        v=min(v,query(u<<1|1,l,r));
    return v;
}
}
int main()
{
    cin>>n>>k;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    Min::build(1,1,n);
    Max::build(1,1,n);
    for(int i=1;i<=n-k+1;i++)
        cout<<Min::query(1,i,i+k-1)<<" ";
    cout<<endl;
    for(int i=1;i<=n-k+1;i++)
        cout<<Max::query(1,i,i+k-1)<<" ";
}

为什么我查询的时候右移了两位还AC了? https://www.luogu.com.cn/record/79773804


by awcyvan @ 2022-07-26 16:21:40

因为你压根就没有用到 \text{mid}


by awcyvan @ 2022-07-26 16:23:09

你计算了 \text{mid} 之后压根没有用它,当然不会出问题


by awcyvan @ 2022-07-26 16:24:00

话说这道题似乎没有必要写线段树


by youyi2008 @ 2022-07-26 16:25:41

@awcyvan az


by youyi2008 @ 2022-07-26 16:26:20

@awcyvan 之前习惯用mid的,可能当时脑子抽了。。。


|