蒟蒻求助:线段树崩了,MLE+TLE

P1440 求m区间内的最小值

yisim @ 2017-07-30 00:27:02

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>

using namespace std;

typedef long long ll;

inline ll read(){
    ll x = 0 , f = 1; char ch = getchar();
    for( ; !isdigit(ch) ; ch = getchar()) if(ch == '-') f = -1;
    for( ; isdigit(ch) ; ch = getchar()) x = x * 10 + ch - '0';
    return x * f;
}

const ll maxn = 2e6 + 1;

ll add[maxn << 2] , sum[maxn << 2];

inline void pushUP(ll root){
    sum[root] = min(sum[root << 1] , sum[root << 1 | 1]);

    return ;
}

inline void pushDOWN(ll node , ll root){
    if(add[root]){
        add[root << 1] += add[root];
        add[root << 1 | 1] += add[root];

        sum[root << 1] += add[root] * (node - (node >> 1));
        sum[root << 1 | 1] += add[root] * (node >> 1);

        add[root] = 0;
    }

    return ;
}

void build(ll _left , ll _right , ll root){
    if(_left == _right){
        sum[root] = read();
        return ;
    }

    ll _mid = (_left + _right) >> 1;
    build(_left , _mid , root << 1);
    build(_mid + 1 , _right , root << 1 | 1);

    pushUP(root);

    return ;
}

void nodeUPDATE(int _left , int _right , int _find , int numAdd , int root){
    if(_left == _right){
        add[root] += numAdd;
        sum[root] += numAdd;
        return ;
    }

    int _mid = _left + (_right - _left) / 2;
    if(_find <= _mid){
        nodeUPDATE(_left , _mid , _find , numAdd , root << 1);
    }
    else {
        nodeUPDATE(_mid + 1 , _right , _find , numAdd , root << 1 | 1);
    }

    pushUP(root);

    return ;
}

void intervalUPDATE(ll begin , ll end , ll _left , ll _right , ll numAdd , ll root){
    if(begin <= _left && _right <= end){
        add[root] += numAdd;
        sum[root] += numAdd * (_right - _left + 1);

        return ;
    }

    pushDOWN(_right - _left + 1 , root);

    ll _mid = (_left + _right) >> 1;
    if(begin <= _mid){
        intervalUPDATE(begin , end , _left , _mid , numAdd , root << 1);
    }
    if(end > _mid){
        intervalUPDATE(begin , end , _mid + 1 , _right , numAdd , root << 1 | 1);
    }

    pushUP(root);

    return ;
}

ll query(ll begin , ll end , ll _left , ll _right , ll root){
    if(begin <= _left && _right <= end){
        return sum[root];
    }

    pushDOWN(_right - _left + 1 , root);

    ll _mid = (_left + _right) >> 1 , ans = 2147483647;
    if(begin <= _mid){
        ans = min(ans , query(begin , end , _left , _mid , root << 1));
    }
    if(end > _mid){
        ans = min(ans , query(begin , end , _mid + 1 , _right , root << 1 | 1));
    }

    return ans;
}

ll n , m;

string opr;

int main(){
    n = read() , m = read();

    build(1 , n , 1);

    puts("0");
    for (ll i = 2 ; i <= n ; i ++){
        if (!m) {
            puts("0");
        }
        else {
            printf("%lld\n" , query(max(1ll , i - m) , i - 1 , 1 , n , 1));
        }
    }
}

by zj余能 @ 2017-08-16 17:37:07

2000000线段树不T才怪


|