【CDOJ】一颗简单的线段树

#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 和 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

猜你喜欢

转载自blog.csdn.net/michaelliu6/article/details/80369437