线段树求调,玄关

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

leiwusi @ 2023-11-13 22:55:45

#include<iostream>
#include<climits>
using namespace std;

const int MAXN = 1e6+114;
int ma[MAXN*4],mi[MAXN*4];

void pushup(int u){
    mi[u] = min(mi[u*2],mi[u*2+1]);
    ma[u] = max(ma[u*2],ma[u*2+1]);
}

void build(int u,int l,int r){
    if(l==r){
        cin>>ma[u];
        mi[u] = ma[u];
        return;
    }
    int mid = (l+r)/2;
    build(u*2,l,mid);
    build(u*2+1,mid+1,r);
    pushup(u);
}

int miquery(int u,int l,int r,int L,int R){
    if(l>r) return INT_MAX;
    if(L<=l&&r<=R){
        return mi[u];
    }
    int mid = (l+r)/2;
    int ans = INT_MAX;
    if(L<mid) ans = min(miquery(u*2,l,mid,L,R),ans);
    if(R>mid) ans = min(miquery(u*2+1,mid+1,r,L,R),ans);
    return ans;
}

int maquery(int u,int l,int r,int L,int R){
    if(l>r) return -INT_MAX;
    if(L<=l&&r<=R){
        return ma[u];
    }
    int mid = (l+r)/2;
    int ans = -INT_MAX;
    if(L<mid) ans = max(maquery(u*2,l,mid,L,R),ans);
    if(R>mid) ans = max(maquery(u*2+1,mid+1,r,L,R),ans);
    return ans;
}

int n,k;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n>>k;
    for(int i=1;i<=4*n+114;i++){
        ma[i]=-INT_MAX;
        mi[i]=INT_MAX;
    }
    build(1,1,n);

    for(int i = 0;i+k<=n;i++){
        cout<<miquery(1,1,n,i,i+k)<<" ";
    }
    cout<<"\n";
    for(int i = 0;i+k<=n;i++){
        cout<<maquery(1,1,n,i,i+k)<<" ";
    }
    return 0;
}

rt


by FFFFFAN @ 2023-11-13 23:09:39

在查询时,你的 if(L<mid) ... 应改为 if(L<=mid) ...,因为 mid 是被包含于左区间的。


by leiwusi @ 2023-11-14 06:14:52

但是改过后还WA,求调rt


by leiwusi @ 2023-11-14 16:14:20

找到问题:\ 1.如你所说\ 2.查询区间由i,i+k改为i,i+k-1


by leiwusi @ 2023-11-14 16:14:47

衣冠@FFFFFAN


|