#include<cstdio> #include<algorithm> #include<iostream> #include<algorithm> using namespace std; #define SIZE 1000005 struct SegmentTree { long long l,r; long long sum,max,min; } t[SIZE*4]; long long a[2000005]; long long n,m; long long x,y; void build(int p, int l, int r) { t[p].l = l;t[p].r=r; if(l == r) { t[p].sum=a[l]; t[p].min=a[l]; t[p].max=a[l]; return; } int mid = (l+r)/2; build(p*2,l,mid); build(p*2+1,mid+1,r); t[p].max=max(t[p*2].max,t[p*2+1].max); t[p].min=min(t[p*2].min,t[p*2+1].min); t[p].sum=t[p*2].sum+t[p*2+1].sum; } void change(int p,int x,int v) { if(t[p].l==t[p].r) { t[p].sum=v; t[p].max=v; t[p].min=v; return; } int mid=(t[p].l+t[p].r)/2; if(x<=mid)change(p*2,x,v); else change(p*2+1,x,v); t[p].sum=t[p*2].sum+t[p*2+1].sum; t[p].max=max(t[p*2].max,t[p*2+1].max); t[p].min=min(t[p*2].min,t[p*2+1].min); } long long asksum(int p, int l, int r) { if(l<=t[p].l&&r>=t[p].r) { return t[p].sum; } int mid = (t[p].l+t[p].r)/2; long long sum=0; if(l<=mid) sum+=asksum(p*2,l,r); if(r>mid) sum+=asksum(p*2+1,l,r); return sum; } long long askmax(int p, int l, int r) { if(l<=t[p].l&&r>=t[p].r) return t[p].max; int mid = (t[p].l+t[p].r)/2; long long val = -1e18; if(l<=mid) val=max(val,askmax(p*2,l,r)); if(r>mid) val=max(val,askmax(p*2+1,l,r)); return val; } long long askmin(int p, int l, int r) { if(l<=t[p].l&&r>=t[p].r) { return t[p].min; } int mid = (t[p].l+t[p].r)/2; long long val = 1e18; if(l<=mid) val=min(val,askmin(p*2,l,r)); if(r>mid) val=min(val,askmin(p*2+1,l,r)); return val; } int main() { scanf("%lld%lld",&n,&m); build(1,1,n); while(m--) { char op[3]; scanf("%s%lld%lld",op,&x,&y); if(op[0]=='0') { change(1,x,y); } else { long long c=asksum(1,x,y)-askmax(1,x,y)-askmin(1,x,y); printf("%lld\n",c) ; } } return 0; }
A - 一棵简单的线段树
Time Limit: 2000 MS Memory Limit: 256 MB
Submit Status
人生已如此艰难,让我们活得轻松一点.
给你一个数组 A[1..n]A[1..n],初始时每个元素都为零.
我会请你帮我对数组完成一些操作.
第一种可能,我会给你两个数 pp 和 xx(1≤p≤n1≤p≤n), 请你帮我把数组的第 pp 个元素替换为 xx, 即 A[p]←xA[p]←x.
第二种可能,我会给你两个数 LL 和 RR(1≤L<R≤n1≤L<R≤n), 请你告诉我 A[L],A[L+1],…,A[R]A[L],A[L+1],…,A[R] 这几个数中去掉一个最大值和一个最小值后剩下的数的和是多少.
好了,现在锅都丢给你了,我可以活得轻松一点了.
Input
输入第一行为一个整数 n (2≤n≤106)n (2≤n≤106),表示数组的大小.
第二行有一个整数 m (1≤m≤106)m (1≤m≤106),表示我需要你帮我完成的任务的个数.
第 33 到 m+2m+2 行每行有 3 个整数 o x yo x y. 如果 o=0o=0,代表我需要使 A[x]←yA[x]←y, 此时 1≤x≤n, |y|≤1091≤x≤n, |y|≤109. 如果 o=1o=1,代表我想知道 A[x],A[x+1],…,A[y]A[x],A[x+1],…,A[y] 去掉一个最大值和一个最小值后剩下的数的和为多少, 此时 1≤x<y≤n1≤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 |