线段树
#include<stdio.h>
#pragma warning (disabled:4996)
#include<malloc.h>
//链表实现
typedef struct Node
{
int Left,Right;
struct Node *LChild,*RChild;
long sum;
}SegNode,*SegTree;
//结构数组
typedef struct Node
{
int Left,Right,Mid;
}SegNode;
//线段树的构造
void CreateSegTree(SegTree T,int left,int right)
{
T=(SegTree)malloc(sizeof(SegNode));
T->Left=left;
T->Right=right;
T->sum=0;//区间和开始化
if(left+1<right)//判断是否是叶结点
{
CreateSegTree(T->LChild,left,(left+right)/2);
CreateSegTree(T->RChild,(left+right)/2,right);
}
else
T->LChild=T->RChild=NULL;
}
//线段树的查询
long QuerySegTree(SegTree T,int left,int right)
{
if(left<=T->Left&&right<=T->Right)
return T->sum;
else
{
long temsum=0;//临时变量,用于求部分和
if(left<(T->Left+T->Right)/2)
temsum=temsum+QuerySegTree(T->LChild,left,right);
if(right>(T->Left+T->Right)/2)
temsum=temsum+QuerySegTree(T->RChild,left,right);
return temsum;
}
}
//线段树的修改
void UpdateSegTree(SegTree T,int t,int delta)
{
if(T->Left==T->Right)//判断是否为修改点
T->sum=T->sum+delta;
else
{
if(t<(T->Left+T->Right)/2)
UpdateSegTree(T->LChild,t,delta);
if(t>(T->Left+T->Right)/2)
UpdateSegTree(T->RChild,t,delta);
T->sum=T->LChild->sum+T->RChild->sum;//用子树的信息更新当前结点
}
}
//采用结构数组储存方式实现建立线段树
void insert(int l,int r,int h,int num)
{
if(SegNode[num].Left==l&&SegNode[num].Right==r)
{
if(SegNode[num].h<h||!SegNode[num].h)
SegNode[num].h=h;
return;
}
if(r<=SegNode[num].Mid)
insert(l,r,h,2*num);
else if(l>=SegNode[num].mid)
insert(l,r,h,2*num+1);
else
{
insert(l,SegNode[num].Mid,h,2*num);
insert(SegNode[num].Mid,r,h,2*num+1);
}
return;
}