用数组实现线段树 ,当前节点为 now,左儿子是now*2右儿子是now*2+1,父节点now/2.注意线段树的数组大小,用 最大子叶个数的4倍。
左儿子为父节点的前半个区间,右儿子 为父节点的后半个区间。
#include <iostream>
#include <algorithm>
#include <string.h>
#include<string>
#include <math.h>
#define MOD 1000000007;
using namespace std;
struct node
{
int v;
int l;
int r;
node(int a, int b, int c)
{
v = a;
l = b;
r = c;
}
node()
{
v = 0;
l = 0;
r = 0;
}
};
node ltree[4000005];
int z[1000005];
int son[1000005];
int creata(int now, int l, int r)
{
ltree[now].l = l;
ltree[now].r = r;
if(l == r)
{
son[l] = now;
ltree[now].v = z[l];
return z[l];
}
int m = (l + r) >> 1;
ltree[now].v = min(creata(now * 2, l, m), creata(now * 2 + 1, m + 1, r));
return ltree[now].v;
}
int find(int now, int l, int r)
{
if(ltree[now].l == l && ltree[now].r == r)
{
return ltree[now].v;
}
int m = (ltree[now].l + ltree[now].r >> 1);
if(r <= m)
{
return find(now * 2, l, r);
}
else
if(l > m)
{
return find(now * 2 + 1, l, r);
}
else
{
return min(find(now * 2, l, m), find(now * 2 + 1, m + 1, r));
}
}
int main()
{
int N, Q, x, y, y2;
while(~scanf("%d", &N))
{
for(int i = 1; i <= N; ++i)
{
scanf("%d", &z[i]);
}
creata(1, 1, N);
scanf("%d", &Q);
for(int i = 0; i < Q; ++i)
{
scanf("%d %d %d", &x, &y, &y2);
if(x)
{
int now = son[y];
ltree[now].v = y2;
while(now > 1)
{
int fa = now / 2;
int _MIN = min(ltree[fa * 2].v, ltree[fa * 2 + 1].v);
if(ltree[fa].v == _MIN)
{
break;
}
else
{
ltree[fa].v = _MIN;
now = fa;
}
}
}
else
{
printf("%d\n", find(1, y, y2));
}
}
}
return 0;
}