线段树
来源:互联网 发布:什么软件可以构图 编辑:程序博客网 时间:2024/05/18 10:11
线段树的模板,基本包括线段树的各个算法了吧。
#include<stdio.h>#include<iostream>using namespace std; /**覆盖区间长度!!**/ /**覆盖区间数统计!!**/long aLeft[10000],aRight[10000],aLow[10000],aHigh[10000],aSum[10000],aFather[10000],len = 0,root = 1;long aChange[10000]; /**aChange[i]是结点i的改变量**/int aCord[10000],aLow_terminal[10000],aHigh_terminal[10000];void build(long a,long b) /**创建原始的线段树**/{ long m; len = len+1; aLow[len] = a; aHigh[len] = b; if(a == b-1) return; /**对每一个结点的Low,High值,所取的区间为(Low,High]**/ /**即为[Low+1,High]**/ /**所以每次构建长度为1..L的线段树时,应为build(0,L);**/ m = len; aLeft[m] = len+1; //aFather[len+1] = m; build(a,(a+b)/2); aRight[m] = len+1; //aFather[len+1] = m; build((a+b)/2,b); return;}void change(long i,long a,long b,long k) /**增减(a,b)区间的值**/{ long mid = (aHigh[i]+aLow[i])/2; if((aLow[i] == a-1)&&(aHigh[i] == b)) { aChange[i] += k; aCord[i] = 1; /**计算覆盖区间长度**/ aLow_terminal[aLow[i]] = 1; aHigh_terminal[aHigh[i]] = 1; return; }else if(a > mid) { aSum[i] += k*(b-a+1); change(aRight[i],a,b,k); } else if(b <= mid) { aSum[i] += k*(b-a+1); change(aLeft[i],a,b,k); } else { aSum[i] += k*(b-a+1); change(aLeft[i],a,mid,k); change(aRight[i],mid+1,b,k); } return;}long quiry(long i,long a) /**查询a这一点的值**/{ long mid = (aHigh[i]+aLow[i])/2; if((aLow[i] == a-1)&&(aHigh[i] == a)) return aChange[i]; if(a <= mid) return aChange[i] + quiry(aLeft[i],a); else return aChange[i] + quiry(aRight[i],a);}long sum(long i,long a,long b) /**计算(a,b)区间的总和**/{ long mid = (aHigh[i]+aLow[i])/2; if((aLow[i] == a-1)&&(aHigh[i] == b)) return aChange[i]*(b-a+1)+aSum[i]; //if((a == b)&&(aHigh[i] == b)) //return aChange[i]+aSum[i]; if(b <= mid) return aChange[i]*(b-a+1)+sum(aLeft[i],a,b); else if (a > mid) return aChange[i]*(b-a+1)+sum(aRight[i],a,b); else return aChange[i]*(b-a+1)+sum(aLeft[i],a,mid)+sum(aRight[i],mid+1,b);}long min(long a,long b){ if(a < b) return a; else return b;}long find_min(long i,long a,long b) /**查找(a,b)区间中的一点最小值**/{ long mid = (aHigh[i]+aLow[i])/2; if(a == b-1) return aChange[i]; if((aLow[i] == a-1)&&(aHigh[i] == b)) return aChange[i]+min(find_min(aLeft[i],a,mid),find_min(aRight[i],mid+1,b)); if(b <= mid) return aChange[i]+find_min(aLeft[i],a,b); else if(a > mid) return aChange[i]+find_min(aRight[i],a,b); else return aChange[i]+min(find_min(aLeft[i],a,mid),find_min(aRight[i],mid+1,b));}long count_length(long i){ long l = 0; if(aCord[i] == 1) return aHigh[i]-aLow[i]; if(aLeft[i] > 0) l += count_length(aLeft[i]); if(aRight[i] > 0) l += count_length(aRight[i]); return l;}long count_total(long i){ if(i == 0) return 0; if(aCord[i] == 1) { if(aLow_terminal[aLow[i]] == 1 && aHigh_terminal[aLow[i]] == 0) return 1; return 0; }else { long m; m = count_total(aLeft[i])+count_total(aRight[i]); return m; }}int main(){ long k = 0; build(0,1000); change(root,50,98,1); //change(root,100,150,1); change(root,100,120,1); //change(root,110,128,1); change(root,124,130,1); change(root,139,150,1); //change(root,160,170,1); //change(root,190,200,1); //change(root,191,199,1); /**cout<<k<<endl; k = quiry(root,122); cout<<k<<endl; k = quiry(root,100); cout<<k<<endl;**/ k = sum(root,100,130); cout<<k<<endl; /**k = find_min(root,100,120); cout<<k<<endl;**/ k = count_length(root); cout<<k<<endl; k = count_total(root); cout<<k<<endl; system("pause"); return 0;}
- 线段树?线段树!
- 线段树?线段树!
- 线段_线段树
- 线段_线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- IIS+花生壳+tomcat:利用免费域名搭建Web站点
- New Git
- 认识批处理中的变量 批处理中字符串的编辑处理【set变量变种】【%date:~0,4%】
- 本地推送 UILocalNotification
- cts测试之压力测试mediastresstest
- 线段树
- Dijkstra 最短路径。
- utf8编码
- HDU_2853 Assignment KM算法
- linux 查看系统信息命令
- Nginx 安装记录
- 一步一步走进字符驱动--原子操作
- hibernate 十一 延迟加载
- 几个国外开源CMS系统比较