啊,是否疲倦了现在的线段树

太弱,还递归!

那我们就欢乐的学习另外一种神奇的线段树吧!(雾

他叫做zkw线段树

 

这个数据结构灰常好写(虽然线段树本身也特别好写……)

速度快(貌似只在单点更新方面比线段树快……)

是一种自底向上非递归版本的线段树!

首先我们来看一个ppt,《统计的力量》这个是发明人的PPT(啊,ppt内的代码是错的……

統計的力量

好吧,我们来写吧~

首先预备条件:

int M,T[maxn*+];

M指的是什么呢?M就指的是这颗zkw线段树最下面的那个点之前的编号是什么

T数组就是这个zkw线段树的数组,由于zkw线段树是一颗满二叉树,所以直接开两倍就好啦~

接下来我们就来建树吧!

以单点更新,区间查询和作为一个例子~

void build(int x)
{
for(M=;M<=n+;M<<); for(int i=;i<=n;i++)
scanf("%d",&T[i+M]); for(int i=M-;i;i--)
T[i]=T[i<<]+T[i<<|];
}

很显然这是一颗非常弱的从底往上更新的树!

然后updata怎么写呢?qsc仔细想了想,很简单

void updata(int n,int val)
{
T[n+=M]=val;//这个地方是单点修改的哟
for(n>>=;n;n>>=)
T[n]=T[n<<]+T[n<<|];
}

哇,其实和线段树是一个意思,直接顺着节点直接往上爬就是了!

query肿么写呢?还是很简单呀

int query(int l,int r)
{
int ans=;
l=l+M-,r=r+M+;
for(;l^r^;l>>,r>>=)
{
if(~l&)ans+=T[l^];
if(r&) ans+=T[r^];
}
return ans;
}

这个乱七八糟的位运算什么意思呀?

l^r^1的意思,就是左边的这个点和右边这个点是否互为兄弟,或者干脆就是一个点

~l&1 就是判断这个左边这个是否为左儿子,r&1判断这个节点是否为右二子

如果是的话,那就得加上他的兄弟咯~

啊,zkw单点更新区间查询就示范到这儿了,是不是灰常简单呀~

我们首先来搞一道例题:

HDU 1166 敌兵布阵 单点更新,区间查询

//qscqesze
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define maxn 200001
#define mod 10007
#define eps 1e-9
//const int inf=0x7fffffff; //无限大
const int inf=0x3f3f3f3f;
/* int buf[10];
inline void write(int i) {
int p = 0;if(i == 0) p++;
else while(i) {buf[p++] = i % 10;i /= 10;}
for(int j = p-1; j >=0; j--) putchar('0' + buf[j]);
printf("\n");
}
*/
//**************************************************************************************
inline ll read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
} ll T[maxn*];
int M,n;
void build()
{
for(M=;M<=n+;M<<=);
for(int i=;i<=n;i++)
T[i+M]=read();
for(int i=M-;i;i--)
T[i]=T[i<<]+T[i<<|];
} void updata(int x,int val)
{
T[x+=M]+=val;
for(x>>=;x>=;x>>=)
{
T[x]=T[x<<]+T[x<<|];
}
} ll query(int l,int r)
{
l=l+M-,r=r+M+;
ll ans=;
for(;l^r^;l>>=,r>>=)
{
if(~l&)ans+=T[l^];
if(r&) ans+=T[r^];
}
return ans;
} int main()
{
int cas=;
int t=read();
string s;
for(int cas=;cas<=t;cas++)
{
memset(T,,sizeof(T));
printf("Case %d:\n",cas);
n=read();
build();
while(cin>>s)
{
if(s[]=='E')
break;
int a,b;
a=read(),b=read();
if(s[]=='A')
updata(a,b);
else if(s[]=='S')
updata(a,-b);
else
printf("%lld\n",query(a,b));
}
}
}

普及向 ZKW线段树!的更多相关文章

  1. ZKW线段树

    简介 zkw线段树虽然是线段树的另一种写法,但是本质上已经和普通的递归版线段树不一样了,是一种介于树状数组和线段树中间的存在,一些功能上的实现比树状数组多,而且比线段树好写且常数小. 普通线段树采用从 ...

  2. zkw线段树详解

    转载自:http://blog.csdn.net/qq_18455665/article/details/50989113 前言 首先说说出处: 清华大学 张昆玮(zkw) - ppt <统计的 ...

  3. BZOJ3173 TJOI2013最长上升子序列(Treap+ZKW线段树)

    传送门 Description 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上升子序列长度是多少? Input ...

  4. 【POJ3468】【zkw线段树】A Simple Problem with Integers

    Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...

  5. HDU 4366 Successor(树链剖分+zkw线段树+扫描线)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4366 [题目大意] 有一个公司,每个员工都有一个上司,所有的人呈树状关系,现在给出每个人的忠诚值和 ...

  6. [SinGuLaRiTy] ZKW线段树

    [SinGuLaRiTy-1007] Copyrights (c) SinGuLaRiTy 2017. All Rights Reserved. 关于ZKW线段树 Zkw线段树是清华大学张昆玮发明非递 ...

  7. 数据结构3——浅谈zkw线段树

    线段树是所有数据结构中,最常用的之一.线段树的功能多样,既可以代替树状数组完成"区间和"查询,也可以完成一些所谓"动态RMQ"(可修改的区间最值问题)的操作.其 ...

  8. 线段树(单标记+离散化+扫描线+双标记)+zkw线段树+权值线段树+主席树及一些例题

    “队列进出图上的方向 线段树区间修改求出总量 可持久留下的迹象 我们 俯身欣赏” ----<膜你抄>     线段树很早就会写了,但一直没有总结,所以偶尔重写又会懵逼,所以还是要总结一下. ...

  9. 『zkw线段树及其简单运用』

    阅读本文前,请确保已经阅读并理解了如下两篇文章: 『线段树 Segment Tree』 『线段树简单运用』 引入 这是一种由\(THU-zkw\)大佬发明的数据结构,本质上是经典的线段树区间划分思想, ...

随机推荐

  1. 执行impdp时出现的各种问题

    1.不同的表空间,不同的用户,不同的表名 impdp ODS_YYJC_BUF_ZB/ODS_YYJC_BUF_ZB job_name=bs3 directory=EXPDMP exclude=OBJ ...

  2. android 动态改变控件位置和大小 .

    动态改变控件位置的方法: setPadding()的方法更改布局位置. 如我要把Imageview下移200px:             ImageView.setPadding( ImageVie ...

  3. nginx allow 多个ip & ipv4的网段表示方法解析

    参考:https://www.baidu.com/link?url=5aVe_syihQzhHnSDAdLsNNQYqDe_W2GYG1GeIQ130e4mEZbusxQfqGVTdg-dJg8fqM ...

  4. SilverLight 浏览器出现滚动条

    照网上说的很多解决方案要不得,最后想了下,直接在body上面加 style="overflow:hidden"解决问题,真觉得微软管理混乱,很多它自己的东西都不支持了.

  5. java经典面试题大全

    基本概念 操作系统中 heap 和 stack 的区别 什么是基于注解的切面实现 什么是 对象/关系 映射集成模块 什么是 Java 的反射机制 什么是 ACID BS与CS的联系与区别 Cookie ...

  6. python爬取漫画

    抓取漫画的网址是:sf互动传媒 抓取漫画的由来也是看了知乎上有人说用爬取漫画,然后自己也玩玩 首页中每个漫画的url是类似这样存储的: <tr> <td height="3 ...

  7. python基础(9)--递归、二叉算法、多维数组、正则表达式

    1.递归 在函数内部,可以调其他函数,如果一个函数在内部调用它本身,这个函数就是递归函数.递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于裂解 递归算法解决问题的特点: 1)递归是 ...

  8. go的匿名组合

    golang也提供了继承机制,但采用组合的文法,因此称为匿名组合.与其他语言不同, golang很清晰地展示出类的内存布局是怎样的. 一  非指针方式的组合 1)基本语法 type base stru ...

  9. hdu 5833(欧拉路)

    The Best Path Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tot ...

  10. 初窥Linux 之 最常用20条命令

    玩过Linux的人都会知道,Linux中的命令的确是非常多,但是玩过Linux的人也从来不会因为Linux的命令如此之多而烦恼,因为我们只需要掌握我们最常用的命令就可以了.当然你也可以在使用时去找一下 ...