区间最小值及其下标
是一道裸题吧
#include<stdio.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string.h>
using namespace std;
#define ls (rt<<1)
#define rs (rt<<1|1)
#define mid ((l+r)>>1)
#define maxn 111111
int mi[maxn<<2];
void up(int rt){mi[rt]=min(mi[ls],mi[rs]);}
void build(int rt,int l,int r){
mi[rt]=0;
if(l==r){
scanf("%d",&mi[rt]);
return ;
}
build(ls,l,mid);
build(rs,mid+1,r);
up(rt);
}
void ins(int rt,int l,int r,int L,int R,int w){
if(L<=l&&r<=R){
mi[rt]+=w;
return ;
}
if(L<=mid)ins(ls,l,mid,L,R,w);
if(mid<R)ins(rs,mid+1,r,L,R,w);
up(rt);
}
int query(int rt,int l,int r){
if(l==r)return l;
if(mi[ls]<=mi[rs])return query(ls,l,mid);
else return query(rs,mid+1,r);
}
int q2(int rt,int l,int r,int L,int R){
if(L<=l&&r<=R){
return mi[rt];
}
int minn=99999999;
if(L<=mid)minn=min(minn,q2(ls,l,mid,L,R));
if(mid<R)minn=min(minn,q2(rs,mid+1,r,L,R));
return minn;
}
int main(){
int n,m;
int t;
scanf("%d",&t);
for(int z=1;z<=t;++z){
scanf("%d",&n);
build(1,1,n);
int a,b;
scanf("%d",&m);
while(m--){
scanf("%d%d",&a,&b);
if(a==0){
int tmp=query(1,1,n);
ins(1,1,n,tmp,tmp,b);
}
else ins(1,1,n,a,a,b);
}
int tmp=query(1,1,n);
printf("Case %d: %d %d\n",z,tmp,q2(1,1,n,tmp,tmp));
}
return 0;
}