线段树后五个点TLE求助
查看原帖
线段树后五个点TLE求助
145523
SMTTY楼主2022/12/7 23:25

考虑l和r的大小关系了,还是tle,佬佬捞捞俺吧

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;

typedef long long ll;

const int N = 100010;

int n, m;
int w[N];

struct Node{
    int l, r;
    ll sum, len;
} tr[N * 4];

void pushup(int u){
    tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
}

void build(int u, int l, int r){
    tr[u] = {l, r, w[r], r - l + 1};
    if (l != r){
        int mid = l + r >> 1;
        build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
        pushup(u);
    }
}

void modify(int u, int l, int r){
    if (tr[u].len == tr[u].sum)
            return;
    if (tr[u].l == tr[u].r){
        tr[u].sum = sqrt(tr[u].sum);
        return;
    }
    int mid = tr[u].l + tr[u].r >> 1;
    if (l <= mid)
        modify(u << 1, l, r);
    if (r > mid)
        modify(u << 1 | 1, l, r);
    pushup(u);
}

ll query(int u, int l, int r){
    if (tr[u].l >= l && tr[u].r <= r)
        return tr[u].sum;
    else{
        int mid = tr[u].l + tr[u].r >> 1;
        ll res = 0;
        if (l <= mid)
            res = query(u << 1, l, r);
        if (r > mid)
            res += query(u << 1 | 1, l, r);
        return res;
    }
}

int main(){
    scanf("%d", &n);
    for (int i = 1; i <= n; i ++ )
        scanf("%d", &w[i]);

    build(1, 1, n);

    scanf("%d", &m);
    int op, l, r;
    while (m -- ){
        scanf("%d%d%d", &op, &l, &r);
        if (l > r)
            swap(l, r);
        if (op == 0)
            modify(1, l, r);
        else
            printf("%lld\n", query(1, l, r));
    }
}
2022/12/7 23:25
加载中...