公元2047年,人类已经无法阻止Ceph入侵地球了!上决╇ф凭借着他的黑科技,在公元2023年研制出了Nanosuit 1.0。二十三年过去了,Nanosuit已经进化到了Nanosuit 3.0版本,具有超强的隐身、护甲、力量等2015年的人不可想象的超人类功能,而且配备了最强大的武器:狩猎弓。上决╇ф为了拯救世界,决定装备上最强的Nanosuit 3.0成为Prophet。
上图为上决╇ф在SWUST之战中使用狩猎弓与很多的Ceph进行战斗,我们可以很清楚地看到,Ceph居然很傻逼地站成了一排,毕竟外星人的世界我们懂不起。再看看,中间那个,体积这么大,肯定攻击力不同寻常,一定要先把这个Ceph干掉!但是,看下一张图,Nanosuit 3.0面罩反射的图:
这是有多少Ceph?不多,也就不超过100000只嘛。拿着狩猎弓慢慢射就行了。
现在的问题是,在这排成一排的Ceph中,上决╇ф想知道,在某个区间内,战斗力最强的Ceph在什么位置,以方便做出作战方案。但是,Ceph毕竟是外星人,战斗力是会变的!我们需要及时第更新数据,告诉上决╇ф他想知道的区间内最强Ceph的位置。
What are you prepared to sacrifice?
Input
第一行,是一个正整数T,表示测试的组数。 对于每一组测试,第一行是一个正整数n,m(1 <= n <= 100000)。代表Ceph的数目和操作次数。 接下来一排,有n个正整数数Ai,(1 <= Ai <= 1000000),分别代表从左往右第i只Ceph的战斗力。 接下来是m次操作。 每次操作为一行,每行有三个正整数op a b。op只可能为1或者2。当op=1时,为询问区间[a,b]内战斗力最强Ceph的位置(1 <= a <= b <= n)。当op=2时,表示在a位置的Ceph战斗力变成了b(1 <= a <=n,1 <= b <= 1000000)。
Output
对于每一次询问,输入区间内最强Ceph 的位置,如果区间内有多个最强Ceph,输入坐靠左边的那个位置。
1 5 3 1 1 1 1 1 1 1 5 2 3 5 1 1 5
1 3
题意:中问题,题意自看
思路:明显线段树,这里是查询一个区间里最值靠左的位置,直接记录一下区间最值和位置即可,放在线段树里面更新即可。
AC代码:#include <stdio.h> #include <string.h> #include <iostream> using namespace std; const int nn = 100005; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 int A[nn]; struct node{ int l,r; int pos,ms; }Tree[nn<<2]; //void Push_Up(int rt) //{ // Tree[rt].ms = max(Tree[rt<<1].ms,Tree[rt<<1|1].ms); // if(Tree[rt].ms==Tree[rt<<1].ms) // { // Tree[rt].pos = Tree[rt<<1].pos; // } // else // { // Tree[rt].pos = Tree[rt<<1|1].pos; // } //} void Push_Up(node &fa,node &ls,node &rs) { fa.l=ls.l,fa.r=rs.r; fa.ms=max(ls.ms,rs.ms); if(fa.ms==ls.ms) { fa.pos=ls.pos; return ; } fa.pos=rs.pos; } void Build(int l,int r,int rt) { Tree[rt].l=l,Tree[rt].r=r; if(l==r) { Tree[rt].ms = A[l]; Tree[rt].pos = l; return ; } int m = (l+r)>>1; Build(lson); Build(rson); Push_Up(Tree[rt],Tree[rt<<1],Tree[rt<<1|1]); } void Update(int pos,int val,int rt) { if(Tree[rt].l==Tree[rt].r) { Tree[rt].ms = val; return ; } int m =(Tree[rt].l+Tree[rt].r)>>1; if(pos<=m) Update(pos,val,rt<<1); else Update(pos,val,rt<<1|1); Push_Up(Tree[rt],Tree[rt<<1],Tree[rt<<1|1]); } //int query_ans(int l,int r,int rt) //{ // if(l<=Tree[rt].l&&Tree[rt].r<=r) // { // return Tree[rt].pos; // } // int t=0; // int m =(Tree[rt].l+Tree[rt].r)>>1; // node tmp[3]; // if(l<=m) tmp[1].pos = query_ans(l,r,rt<<1),t++; // if(m<r) tmp[2].pos = query_ans(l,r,rt<<1|1),t+=2; // if(t<3)return tmp[t].pos; // Push_Up(tmp[0],tmp[1],tmp[2]); // return tmp[0].pos; //} node query(int id,int l,int r) { if(l<=Tree[id].l&&Tree[id].r<=r) return Tree[id]; int mid=(Tree[id].l+Tree[id].r)>>1; node tmp[3]; int t=0; if(mid>=l) tmp[1]=query(id<<1,l,r),t++; if(mid<r) tmp[2]=query(id<<1|1,l,r),t+=2; if(t<3) return tmp[t]; Push_Up(tmp[0],tmp[1],tmp[2]); return tmp[0]; } int main() { int tt,n,q; int op,a,b; scanf("%d",&tt); while(tt--) { scanf("%d%d",&n,&q); for(int i=1;i<=n;i++) scanf("%d",&A[i]); Build(1,n,1); while(q--) { scanf("%d%d%d",&op,&a,&b); if(op==1) { node ans=query(1,a,b); printf("%d\n",ans.pos); } else Update(a,b,1); } } return 0; }