公元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;
}