最大最小值
时间限制:1000 ms | 内存限制:65535 KB
难度:2
- 描述
-
给出N个整数,执行M次询问。对于每次询问,首先输入三个整数C、L、R:
如果C等于1,输出第L个数到第R个数之间的最小值;
如果C等于2,输出第L个数到第R个数之间的最大值;
如果C等于3,输出第L个数到第R个数之间的最小值与最大值的和。
(包括第L个数和第R个数)。
- 输入
- 首先输入一个整数T(T≤100),表示有T组数据。
对于每组数据,先输入一个整数N(1≤N≤10000),表示有N个整数;
接下来一行有N个整数a(1≤a≤10000);
然后输入一个整数M,表示有M次询问;
接下来有M行(1≤M≤10000),每行有3个整数C、L、R(1≤C≤3,1≤L≤R≤N)。
- 输出
- 按照题意描述输出。每个输出占一行。
- 样例输入
-
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; }
时间: 2024-11-06 11:52:46