线段树做法求助

P1440 求m区间内的最小值

Gypsophila @ 2017-11-23 22:11:35

#include <bits/stdc++.h>
#define ll int
using namespace std;
ll n, m;
ll L = 1, a[500100];
struct st
{
    ll left, right;
    ll lazy, s;
}t[500005];

inline int read() 
{
    int x=0, f = 1; 
    char ch=getchar();
    while(ch > '9' || ch < '0')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x *= 10; 
        x += (ch-'0');
        ch = getchar();
    }
    return x * f;
}

inline void write(int x)
{
    if(x < 0) putchar('-'), x = -x;
    if(x > 9) write(x / 10);
    putchar(x % 10 + '0');
}
void build_tree()
{
    while(L < n) L *= 2;
    for(ll i = 1; i <= n; i++) 
        t[i + L - 1].left = t[i + L - 1].right = i, 
        t[i + L - 1].s = a[i];
    for(ll i = L + n;i < 2 * L;i++)
        t[i].left = t[i].right = i - L + 1;
    for(ll i = L - 1; i >= 1; i--)
        t[i].left = t[2 * i].left,
        t[i].right = t[2 * i + 1].right,
        t[i].s = min(t[2 * i + 1].s, t[2 * i].s);
}
ll query(ll id, ll left, ll right)
{
    if(t[id].left == left && t[id].right == right)
        return t[id].s;
    if(t[2 * id].right >= right) return query(2 * id, left, right);
    else if(t[2 * id + 1].left <= left) return query(2 * id + 1, left, right);
    else return min(query(2 * id, left, t[2 * id].right), query(2 * id + 1, t[2 * id + 1].left, right));
}
int main(int argc, char *argv[])
{
    n = read();
    m = read();
    for(int i = 1; i <= n; i++) a[i] = read();
    build_tree();
    for(int i = 1; i <= n; i++)
    {
        if(i == 1) write(0);
        else if(i <= m) write(query(1, 1, i - 1));
        else if(i > m) write(query(1, i - m, i - 1));
        printf("\n");
    }
    return 0;
}
#2加了输入输出后卡过(900ms+),#10永远的TLE求大佬优化。

by Gypsophila @ 2017-11-23 22:12:15

是输入输出优化。。。


by iodwad @ 2017-11-23 23:15:38

这道题好像线段树会卡掉吧


by sjkmost @ 2017-11-23 23:49:53

这题线段树复杂度是错的

不过你可以加个fread,fwrite,位运算试一试能不能卡过


by 紫钦 @ 2017-11-24 06:26:32

亲测zkw是可以过的。


by Gypsophila @ 2017-11-24 06:39:21

谢谢大佬们


by Wolfycz @ 2017-11-24 14:15:11

其实这题可以用单调队列的


by 青石巷 @ 2017-11-24 14:49:21

本来单调队列就是正解啊……


by 青石巷 @ 2017-11-24 14:50:00

虽然标准RMQ也可以(逃


by 权御天下 @ 2018-05-02 23:17:03

@ACの666 @青石巷 @ZCDHJ @sjkmost 我拿zkw试着优化了一下常数,不加I/O优化的话点2和点10都是640ms左右 卡常数万岁


by kma_093 @ 2018-09-10 17:38:16

线段树吸氧能过,不吸氧t1个实在是改不出了……


|