动态最值(minmax.Cpp/c/java)
(空间限制128M)
有一个包含n个元素的数组,要求实现以下操作:
DELETE k:删除位置k上的数。右边的数往左移一个位置。
QUERY i j:查询位置i~j上所有数的最小值和最大值。
【输入】(minmax.in)
输入第一行包含两个数n, m,表示原始数组的元素个数和操作的个数。第二行包括n个数,表示原始数组。以下m行,每行格式为1 k或者2 i j,其中第一个数为1表示删除操作,为2表示询问操作。
【输出】(minmax.out)
输出一行,包括两个数,表示该范围内的最小值和最大值。
【样例输入】
10 4
1 5 2 6 7 4 9 3 1 5
2 2 8
1 3
1 6
2 2 8
【样例输出】
2 9
1 7
【限制】
数组中的元素绝对值均不超过109
第一组:n = 10, 1 分, 时限 0.1s
第二组:n = 333, 2 分, 时限 0.1s
第三组:n = 4232,3分, 时限 0.1s
第四组:n = 6324, 4分, 时限 0.2s
第五组:n = 9999, 5分, 时限 2s
第六组:n = 100000, m = 300000, 10分,时限 2s
第七组:n = 300000, m = 422342, 13分,时限 3s
第八组:n = 500000, m = 651222, 18分,时限 3s
第九组:n = 900000, m = 432122, 22分,时限 5s
第十组:n = 999999,m = 999999,22分,时限 5s
/************************ author : Grant Yuan time : 2014/10/4 18:06 source : 十一第二场 algorithm: 线段树 *************************/ #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #define INF 0x7fffffff #define MAX 1000007 using namespace std; struct node { int l; int r; int Min; int Max; int num; }; node tree[4*MAX]; int n,m; int input[MAX]; int ansmin,ansmax; void build(int left,int right,int root) { tree[root].l=left; tree[root].r=right; if(left==right){ tree[root].Max=tree[root].Min=input[left]; tree[root].num=1; return; } int mid=(left+right)>>1; build(left,mid,root*2); build(mid+1,right,root*2+1); tree[root].Max=max(tree[root*2].Max,tree[root*2+1].Max); tree[root].Min=min(tree[root*2].Min,tree[root*2+1].Min); tree[root].num=tree[root*2].num+tree[root*2+1].num; } void query(int left,int right,int root) { if(left==1&&(right==tree[root].num)) { ansmin=min(ansmin,tree[root].Min); ansmax=max(ansmax,tree[root].Max); return; } int n1=tree[root*2].num; int n2=tree[root*2+1].num; if(left<=n1&&right>n1) {query(left,n1,root*2); query(1,right-n1,root*2+1);} else if(left<=n1&&right<=n1) query(left,right,root*2); else if(left>n1&&right<=n1+n2) query(left-n1,right-n1,root*2+1); } void Delete(int num,int root) { if((tree[root].l==tree[root].r)) { tree[root].num=tree[root].num-1; tree[root].Min=INF;tree[root].Max=-INF; return; } int n1=tree[root*2].num; int n2=tree[root*2+1].num; if(num<=n1) Delete(num,root*2); else Delete(num-n1,root*2+1); tree[root].num=tree[root*2].num+tree[root*2+1].num; tree[root].Max=max(tree[root*2].Max,tree[root*2+1].Max); tree[root].Min=min(tree[root*2].Min,tree[root*2+1].Min); } int main() { freopen("minmax.in", "r",stdin); freopen("minmax.out", "w", stdout); while(~scanf("%d%d",&n,&m)){ for(int i=1;i<=n;i++) { scanf("%d",&input[i]); } for(int i=1;i<=4*n;i++) tree[i].Min=INF,tree[i].Max=-INF; build(1,n,1); int a,b,c; for(int i=1;i<=m;i++) { scanf("%d",&a); if(a==1){ scanf("%d",&b); Delete(b,1); } else if(a==2){ ansmin=INF;ansmax=-INF; scanf("%d%d",&b,&c); query(b,c,1); printf("%d %d ",ansmin,ansmax); } } } return 0; }