zkw 线段树
2024-09-04 03:08:35
优秀的 zkw 线段树讲解:《线段树的扩展之浅谈 zkw 线段树》
存一份模板代码(区间修改、区间查询):
/* zkw Segment Tree
* Au: GG
*/
#include <cstdio>
typedef long long ll;
const int N=1e5+3;
int n, m, zkw; ll t[N<<2], laz[N<<2];
inline void update(int x, int y, ll val) {
ll l=0, r=0, f=1;
for (x+=zkw-1, y+=zkw+1; x^y^1; x>>=1, y>>=1, f<<=1) {
t[x]+=val*l, t[y]+=val*r;
if (~x&1) laz[x^1]+=val, t[x^1]+=val*f, l+=f;
if (y&1) laz[y^1]+=val, t[y^1]+=val*f, r+=f;
}
for (; x; x>>=1, y>>=1) t[x]+=val*l, t[y]+=val*r;
}
inline ll query(int x, int y) {
ll res=0, l=0, r=0, f=1;
for (x+=zkw-1, y+=zkw+1; x^y^1; x>>=1, y>>=1, f<<=1) {
if (laz[x]) res+=laz[x]*l;
if (laz[y]) res+=laz[y]*r;
if (~x&1) res+=t[x^1], l+=f;
if (y&1) res+=t[y^1], r+=f;
}
for (; x; x>>=1, y>>=1) res+=laz[x]*l, res+=laz[y]*r;
return res;
}
int main() {
scanf("%d%d", &n, &m);
for (zkw=1; zkw<=n+1; zkw<<=1);
for (int i=zkw+1; i<=zkw+n; i++) scanf("%lld", t+i);
for (int i=zkw-1; i>0; --i) t[i]=t[i<<1]+t[i<<1|1];
while (m--) {
int opt, a, b; ll c; scanf("%d%d%d", &opt, &a, &b);
if (opt<2) scanf("%lld", &c), update(a, b, c);
else printf("%lld\n", query(a, b));
}
return 0;
}
最新文章
- Symantec Backup Exec 2010 Agent For Linux安装
- Wireshark抓包工具
- ID3、C4.5、CART、RandomForest的原理
- maven 项目无法发布,无法编译的解决办法
- React入门简单实践
- (转)android图片压缩总结
- rabbitmq_config
- web工程目录结构
- MongoDB学习笔记-创建、更新、删除文档
- C#中OpenFileDialog的使用
- 通往WinDbg的捷径
- 抓包工具 - Fiddler(详细介绍)
- Java设计模式之职责链设计模式
- 书写Css文件要点
- 在nuget上发布自己的程序集教程
- [leetcode]32. Longest Valid Parentheses最长合法括号子串
- 注解 和 xml 配置的优缺点【转】
- Python基础之模块以及5大模块的使用
- Linux -- 基于zookeeper的java api(二)
- 2019.02.09 bzoj2440: [中山市选2011]完全平方数(二分答案+容斥原理)