http://acm.hdu.edu.cn/webcontest/contest_show.php?cid=7875 做题的网址
pp:最近做题,诸事不顺。每次去机房都没有一丝丝的开心。有时候自己好不容易理解了点,写了一点,但总是有各种状况过不了, 但我又找不出错误,那种时候真的很急躁。。。吃饭饭不香的感觉很让人苦恼。后来我认真的调整了一下自己的状态,觉得自己怎么也不能被吓死。学一点是一点,不要对不起今天,明天。
建树:
void build(int l,int r,int rt) { if(l==r) return ; int mid=(l+r)>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); }
单点更新:
void Updata(int node, int begin, int end, int ind, int add)/*单节点更新*/ { if( begin == end ) { segTree[node] += add; return ; } int m = ( left + right ) >> 1; if(ind <= m) Updata(node * 2,left, m, ind, add); else Updata(node * 2 + 1, m + 1, right, ind, add); /*回溯更新父节点*/ segTree[node] = min(segTree[node * 2], segTree[node * 2 + 1]); }
区间更新:
void Change(node *p, int a, int b) /* 当前考察结点为p,修改区间为(a,b]*/ { if (a <= p->Left && p->Right <= b) /* 如果当前结点的区间包含在修改区间内*/ { ...... /* 修改当前结点的信息,并标上标记*/ return; } Push_Down(p); /* 把当前结点的标记向下传递*/ int mid = (p->Left + p->Right) / 2; /* 计算左右子结点的分隔点 if (a < mid) Change(p->Lch, a, b); /* 和左孩子有交集,考察左子结点*/ if (b > mid) Change(p->Rch, a, b); /* 和右孩子有交集,考察右子结点*/ Update(p); /* 维护当前结点的信息(因为其子结点的信息可能有更改)*/ }
区间查询:
int query(int node, int begin, int end, int left, int right) { int p1, p2; /* 查询区间和要求的区间没有交集 */ if (left > end || right < begin) return -1; /* if the current interval is included in */ /* the query interval return segTree[node] */ if (begin >= left && end <= right) return segTree[node]; /* compute the minimum position in the */ /* left and right part of the interval */ p1 = query(2 * node, begin, (begin + end) / 2, left, right); p2 = query(2 * node + 1, (begin + end) / 2 + 1, end, left, right); /* return the expect value */ if (p1 == -1) return p2; if (p2 == -1) return p1; if (p1 <= p2) return p1; return p2; }