萌新求助 用线段树又wa又T

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

Rumfineo @ 2019-08-26 22:01:23

RT


#include<bits/stdc++.h>
#define ls(x) x<<1
#define rs(x) x<<1|1
#define m(x,y)(x+y)>>1
#define MAXN 1000001
using namespace std;
long long a[MAXN],minn[MAXN<<2],maxn[MAXN<<2];
long long n,m;

void build(long long k,long long l,long long r)
{
    if(l==r)    {minn[k]=maxn[k]=a[l];return;}
    long long mid=m(l,r);
    build(ls(k),l,mid);
    build(rs(k),mid+1,r);
    minn[k]=min(minn[ls(k)],minn[rs(k)]);
    maxn[k]=max(maxn[ls(k)],maxn[rs(k)]);
}

long long get_min(long long k,long long ql,long long qr,long long l,long long r)
{
    long long ans=0x3f3f3f3f;
    if (ql<=l&&qr>=r)   return minn[k];
    long long mid=m(l,r);
    if (ql<=mid)    ans=min(ans,get_min(ls(k),ql,qr,l,mid));
    if (qr>mid)     ans=min(ans,get_min(rs(k),ql,qr,mid+1,r));
    return ans;
}

long long get_max(long long k,long long ql,long long qr,long long l,long long r)
{
    long long ans=0;
    if (ql<=l&&qr>=r)   return maxn[k];
    long long mid=m(l,r);
    if (ql<=mid)    ans=max(ans,get_max(ls(k),ql,qr,l,mid));
    if (qr>mid)     ans=max(ans,get_max(rs(k),ql,qr,mid+1,r));
    return ans;
}

int main()
{
    cin>>n>>m;
    for (long long i=1;i<=n;i++)  cin>>a[i];
    build(1,1,n);
    for (long long i=1;i<=(n-m+1);i++)    
        printf("%lld ",get_min(1,i,i+m-1,1,n));
    cout<<endl;
    for (long long i=1;i<=(n-m+1);i++)
        printf("%lld ",get_max(1,i,i+m-1,1,n));
    return 0;
}

by 7KByte @ 2019-08-26 22:05:51

单调队列


by 樱初音斗橡皮 @ 2019-08-26 22:06:24

这题就不是线段树题


by Rumfineo @ 2019-08-26 22:07:51

可是标签上有线段树,而且线段树也是能做的啊


by tanao @ 2019-08-26 22:12:09

T不是很正常吗?

WA的话,自己调呗(滑稽.jpg


by ⚡小林孑⚡ @ 2019-08-26 22:15:02

@Rumfineo 线段树+RMQ能做,但效率极低
总结:可以,但没必要


by    吾皇 @ 2019-08-26 22:21:28

优先队列可做


by Lice @ 2019-08-26 22:25:20

@Rumfineo 你用了两次"get_sth",为什么不写成结构体传输答案?这样就只要一次查询了。。。

Ps:要做也是用st表啊


by Lice @ 2019-08-26 22:27:21

或者吸氧 卡卡常


|