UESTC DS A 一颗简单的线段树 线段树

A - 一棵简单的线段树

Time Limit: 2000 MS     Memory Limit: 256 MB
Submit Status

人生已如此艰难,让我们活得轻松一点.

给你一个数组 A[1..n]A[1..n],初始时每个元素都为零.

我会请你帮我对数组完成一些操作.

第一种可能,我会给你两个数 pp 和 xx1pn1≤p≤n), 请你帮我把数组的第 pp 个元素替换为 xx, 即 A[p]xA[p]←x.

第二种可能,我会给你两个数 LL 和 RR1L<Rn1≤L<R≤n), 请你告诉我 A[L],A[L+1],,A[R]A[L],A[L+1],…,A[R] 这几个数中去掉一个最大值和一个最小值后剩下的数的和是多少.

好了,现在锅都丢给你了,我可以活得轻松一点了.

Input

输入第一行为一个整数 n (2n106)n (2≤n≤106),表示数组的大小.

第二行有一个整数 m (1m106)m (1≤m≤106),表示我需要你帮我完成的任务的个数.

第 33 到 m+2m+2 行每行有 3 个整数 o x yo x y. 如果 o=0o=0,代表我需要使 A[x]yA[x]←y, 此时 1xn, |y|1091≤x≤n, |y|≤109. 如果 o=1o=1,代表我想知道 A[x],A[x+1],,A[y]A[x],A[x+1],…,A[y] 去掉一个最大值和一个最小值后剩下的数的和为多少, 此时 1x<yn1≤x<y≤n.

Output

对每个 o=1o=1 的任务, 输出只有一个整数的一行, 该整数表示区间 [x,y][x,y] 中的数 去掉一个最大值和一个最小值后剩下的数的和.

Sample input and output

Sample Input Sample Output
5
5
0 2 1
0 4 -2
1 1 5
0 1 5
1 1 4
0
1
























对于这题 只要单点更新 三个数组up一下 就可以出答案了

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAX_N = 100010;
int MAX[MAX_N<<2],MIN[MAX_N<<2],s[MAX_N<<2];
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
void up(int p){
    MAX[p] = max(MAX[p*2],MAX[p*2+1]);
    MIN[p] = min(MIN[p*2],MIN[p*2+1]);
    s[p] = s[p*2] + s[p*2+1];
}
void build(int p,int l,int r){
    if(l==r){
        MAX[p] = MIN[p] = s[p] = 0;
        return ;
    }
    int mid =(l+r)>>1;
    build (p*2,l,mid);
    build(p*2+1,mid+1,r);
    up(p);
}
void change(int p,int l,int r,int x,int v){
    if(l==r){
        MAX[p]=MIN[p]=s[p] = v;
        return;
    }
    int mid =(l+r)>>1;
    if(x<=mid) change(p*2,l,mid,x,v);
    else change(p*2+1,mid+1,r,x,v);
    up(p);
}
void query(int p,int l,int r,int x,int y,int& sum,int& maxx,int& minn){
    if(x<=l&&r<=y){
        sum += s[p];
        maxx=max(MAX[p],maxx);
        minn=min(MIN[p],minn);
        return;
    }
    int mid = (l+r)>>1;
    if(x<=mid) query(p*2,l,mid,x,y,sum,maxx,minn);
    if(y>mid) query(p*2+1,mid+1,r,x,y,sum,maxx,minn);
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    build(1,1,n);
    while(m--){
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        if(a==0){
            change(1,1,n,b,c);
        }
        else if(a==1){
            int sum = 0;
            int maxx= -0x3f3f3f3f;
            int minn= 0x3f3f3f3f;
            query(1,1,n,b,c,sum,maxx,minn);
            printf("%d\n",sum-maxx-minn);
        }
    }

    return 0;
}

























猜你喜欢

转载自blog.csdn.net/heucodesong/article/details/80690494