zkw线段树分析
来源:互联网 发布:windows启动错误恢复 编辑:程序博客网 时间:2024/05/18 02:54
具体内容见 ppt《统计的力量》
我目前能解决的问题有
1.单点更新+区间求和/求最值
2.区间加减一个数+区间求最值
前缀和的前缀和无思路
1.单点更新+区间求和/求最值
注意此实现在存储的时候从 M+1 开始存
即对于下图 分别从5和9开始存储到6和14 另说明了zkw线段树在存储上是堆的结构
代码以hdu1754为例
#include <iostream>#include <algorithm>#include <cmath>#include <cstdio>#include <cstring>using namespace std;const int maxn = 200000;int T[maxn<<2];int M;#define PUSHUP(x) T[x] = max(T[x+x],T[x+x+1])void build_tree(int n){ for(M=1;M <= n+1;M<<=1); memset(T,0,sizeof(int) * (M+M)); for(int i = 1;i<=n;i++) scanf("%d",T+i+M); for(int i = (M+n)/2;i;i--) PUSHUP(i);}int query_tree(int s,int t){ int ans = 0; for(s = s+M-1,t=t+M+1;s^t^1;s>>=1,t>>=1) { if(~s&1) ans = max(ans,T[s^1]); if(t&1) ans = max(ans,T[t^1]); } return ans;}void fix_tree(int p,int v){ for(T[p+=M]=v,p>>=1;p;p>>=1) PUSHUP(p);}int main(){ int n,m,a,b; char op[5]; while(~scanf("%d%d",&n,&m)) { build_tree(n); while(m--) { scanf("%s%d%d",op,&a,&b); if(op[0]=='Q')printf("%d\n",query_tree(a,b)); else fix_tree(a,b); } }}
2.区间加减一个数+区间求最值
即利用差分思路
维护这样一种树
例如 a是b,c的父节点 那么 a = max(b,c);b -= a; c-=a;
上面是求最大值 求最小值改成min即可
以3 9 5 8为例
[图片]
求max的源码 min与之类似
#include <iostream>#include <cmath>#include <algorithm>#include <cstring>#include <cstdio>using namespace std;const int maxn = 200000;int T[maxn<<2];int M;void build_tree(int n){ for(M=1;M<=n+1;M<<=1); memset(T,0,sizeof(int)*(M+M)); for(int i = 1;i<=n;i++) scanf("%d",T+i+M);int A; for(int i = (n+M)/2;i;i--) { A = max(T[i+i],T[i+i+1]);T[i+i] -= A;T[i+i+1] -=A;T[i] += A;}}int query_tree(int s,int t){ int Lans=0,Rans=0,ans=0; for(s=s+M,t=t+M;s^t^1;s>>=1,t>>=1) { Lans += T[s]; Rans += T[t]; if(~s&1)Lans = max(Lans,T[s^1]); if(t&1) Rans = max(Rans,T[t^1]); } ans = max(Lans,Rans); while(s>1)ans += T[s>>=1]; return ans;}void fix_tree(int s,int t,int x){ int A; for(s=s+M-1,t=t+M+1;s^t^1;s>>=1,t>>=1) { if(~s&1) T[s^1]+=x; if(t&1) T[t^1]+=x; A = max(T[s],T[s^1]);T[s]-=A;T[s^1]-=A;T[s>>1]+=A; A = max(T[t],T[t^1]);T[t]-=A;T[t^1]-=A;T[t>>1]+=A; } for(;s>1;s>>=1) { A = max(T[s],T[s^1]);T[s]-=A;T[s^1]-=A;T[s>>1]+=A; }}int main(){ int n; cin >> n; build_tree(n);// for(int i = 0;i<=50;i++)// cout << i<<":"<<T[i]<<endl;// cout << query_tree(1,14)<<endl;// fix_tree(2,4,2); // fix_tree(3,5,2);// fix_tree(4,6,2); // cout << query_tree(1,14)<<endl; return 0;}
0 0
- zkw线段树分析
- zkw线段树 运用
- 【zkw线段树】ural1855
- ZKW线段树
- POJ3468 ZKW线段树
- ZKW线段树
- zkw线段树 模板
- ZKW线段树
- zkw线段树
- zkw线段树
- ZKW 线段树
- zkw线段树
- zkw线段树详解
- zkw线段树
- poj3468 zkw线段树
- zkw线段树
- zkw线段树
- zkw线段树详解
- 2016年第七届蓝桥杯省赛C组试题
- Java开发流程自动化(svn+maven+nexus+jenkins) --自动编译,持续集成,测试,打包,发布/部署
- Java对象的创建过程
- 使用GitHub Pages + Hexo 快速搭建个性化博客(四)-博客菜单和侧边栏优化
- 面向对象上-2
- zkw线段树分析
- winfrom上传多个文件到指定文件夹
- 不安
- Activity中finish()和onDestroy()的区别
- PAT Basic 1053. 住房空置率 (20)
- Hadoop 1.x 编写自己的WordCount程序
- 过滤script文件
- Android缩放图片加载大图片
- 2016年第七届蓝桥杯省赛A组试题