如果C等于1,输出第L个数到第R个数之间的最小值;
如果C等于2,输出第L个数到第R个数之间的最大值;
如果C等于3,输出第L个数到第R个数之间的最小值与最大值的和。
2 4 1 3 2 4 2 1 1 4 2 2 3 5 1 2 3 4 5 1 3 1 5
1 3 6
//通过线段树记录一个区间中的最大值以及最小值
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int T,N,M,C,L,R;
const int maxn=10000+5;
struct digit {
int mins,maxs;
} sum[maxn<<2];
void pushup(int rt) {
sum[rt].maxs=max(sum[rt<<1].maxs,sum[rt<<1|1].maxs);
sum[rt].mins=min(sum[rt<<1].mins,sum[rt<<1|1].mins);
}
void build(int rt,int l,int r) {
if(l==r) {
scanf("%d",&sum[rt].mins);
sum[rt].maxs=sum[rt].mins;
return;
}
int mid=(l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
pushup(rt);
}
int query(int kind,int L,int R,int rt,int l,int r) {
if(L<=l&&r<=R) {
if(kind==1) return sum[rt].mins;
else return sum[rt].maxs;
}
int mid=(l+r)>>1;
int res;
if(kind==1)res=1000000;
else res=0;
if(L<=mid) {
if(kind==1) res=min(query(kind,L,R,rt<<1,l,mid),res);
else res=max(query(kind,L,R,rt<<1,l,mid),res);
}
if(R>mid) {
if(kind==1) res=min(query(kind,L,R,rt<<1|1,mid+1,r),res);
else res=max(query(kind,L,R,rt<<1|1,mid+1,r),res);
}
return res;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("D://imput.txt","r",stdin);//需要去掉
#endif // ONLINE_JUDGE
scanf("%d",&T);
while(T--) {
scanf("%d",&N);
build(1,1,N);
scanf("%d",&M);
while(M--) {
scanf("%d%d%d",&C,&L,&R);
int res;
if (C==1) printf("%d\n",query(1,L,R,1,1,N));
else if(C==2) printf("%d\n",query(2,L,R,1,1,N));
else printf("%d\n",query(1,L,R,1,1,N)+query(2,L,R,1,1,N));
}
}
return 0;
}
原文:http://blog.csdn.net/qq_18661257/article/details/46592133