线段树

来源:互联网 发布:江苏泗洪网络问政平台 编辑:程序博客网 时间:2024/06/05 17:34

用数组实现线段树 ,当前节点为 now,左儿子是now*2右儿子是now*2+1,父节点now/2.注意线段树的数组大小,用 最大子叶个数的4倍。

左儿子为父节点的前半个区间,右儿子 为父节点的后半个区间。




#include <stdio.h>

#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;
}
0 0
原创粉丝点击