树状数组 && 线段树
树状数组
支持单点修改
#include <cstdio> using namespace std; int n, m;
int a[], c[]; int lowbit(int x)
{
return x & -x;
} int sum(int x)
{
int ans = ;
while(x)
{
ans += c[x];
x -= lowbit(x);
}
return ans;
} void add(int x, int d)
{
while(x <= n)
{
c[x] += d;
x += lowbit(x);
}
} int main()
{
int i, j, x, y, z;
scanf("%d %d", &n, &m);
for(i = ; i <= n; i++)
{
scanf("%d", &a[i]);
add(i, a[i]);
}
for(i = ; i <= m; i++)
{
scanf("%d %d %d", &z, &x, &y);
if(z == ) add(x, y);
else printf("%d\n", sum(y) - sum(x - ));
}
return ;
}
支持区间修改
#include <cstdio>
#include <iostream> using namespace std; int n, m;
long long c0[], c1[], a[]; long long lowbit(int x) {return x & -x;} long long sum(long long *c, int x)
{
long long ans = ;
while(x)
{
ans += c[x];
x -= lowbit(x);
}
return ans;
} void add(long long *c, int x, int d)
{
while(x <= n)
{
c[x] += d;
x += lowbit(x);
}
} int main()
{
int i, j, x, y, z, k;
long long ans;
scanf("%d%d", &n, &m);
for(i = ; i <= n; i++)
{
scanf("%d", &a[i]);
add(c0, i, a[i]);
}
for(i = ; i <= m; i++)
{
scanf("%d%d%d", &z, &x, &y);
if(z == )
{
scanf("%d", &k);
add(c0, x, -k * (x - ));
add(c1, x, k);
add(c0, y + , k * y);
add(c1, y + , -k);
}
else
{
ans = ;
ans += sum(c0, y) + sum(c1, y) * y;
ans -= sum(c0, x - ) + sum(c1, x - ) * (x - );
printf("%lld\n", ans);
}
}
return ;
}
线段树
支持区间修改
add[o]表示节点o的lazy标记,且节点o已经修改完
#include <cstdio>
#include <cstring>
#include <iostream> using namespace std; #define root 1, 1, N
#define ls o << 1, l, m
#define rs o << 1 | 1, m + 1, r int L, R;
long long add[], mul[], c[], P; inline int read()
{
int x = , f = ;
char ch = getchar();
while(!isdigit(ch))
{
if(ch == '-') f = -;
ch = getchar();
}
while(isdigit(ch))
{
x = x * + ch - '';
ch = getchar();
}
return x * f;
} inline void pushup(int o)
{
c[o] = (c[o << ] + c[o << | ]) % P;
} inline void build(int o, int l, int r)
{
add[o] = ;
mul[o] = ;
if(l == r)
{
scanf("%lld", &c[o]);
return;
}
int m = (l + r) >> ;
build(ls);
build(rs);
pushup(o);
} inline void pushdown(int o, int m)
{
if(add[o] == && mul[o] == ) return;
c[o << ] = (c[o << ] * mul[o] + add[o] * (m - (m >> ))) % P;
c[o << | ] = (c[o << | ] * mul[o] + add[o] * (m >> )) % P;
add[o << ] = (add[o << ] * mul[o] + add[o]) % P;
add[o << | ] = (add[o << | ] * mul[o] + add[o]) % P;
mul[o << ] = (mul[o << ] * mul[o]) % P;
mul[o << | ] = (mul[o << | ] * mul[o]) % P;
add[o] = ;
mul[o] = ;
} inline void update(int f, int d, int o, int l, int r)
{
if(L <= l && r <= R)
{
if(f == )
{
add[o] = (add[o] + d) % P;
c[o] = (c[o] + d * (r - l + )) % P;
}
else
{
mul[o] = (mul[o] * d) % P;
add[o] = (add[o] * d) % P;
c[o] = (c[o] * d) % P;
}
return;
}
pushdown(o, r - l + );
int m = (l + r) >> ;
if(L <= m) update(f, d, ls);
if(m < R) update(f, d, rs);
pushup(o);
} inline long long query(int o, int l, int r)
{
if(L <= l && r <= R) return c[o];
pushdown(o, r - l + );
int m = (l + r) >> ;
long long ret = ;
if(L <= m) ret += query(ls);
if(m < R) ret += query(rs);
return ret;
} int main()
{
int N, Q;
N = read();
P = read();
build(root);
Q = read();
while(Q--)
{
int a, x, y, k;
a = read();
if(a == || a == )
{
x = read();
y = read();
k = read();
L = x;
R = y;
update(a, k, root);
}
else
{
x = read();
y = read();
L = x;
R = y;
printf("%lld\n", query(root) % P);
}
}
return ;
}
ps:有意思的是这个代码还是[AHOI2009]维护序列的题解
树状数组 && 线段树的更多相关文章
- 洛谷P2414 阿狸的打字机 [NOI2011] AC自动机+树状数组/线段树
正解:AC自动机+树状数组/线段树 解题报告: 传送门! 这道题,首先想到暴力思路还是不难的,首先看到y有那么多个,菜鸡如我还不怎么会可持久化之类的,那就直接排个序什么的然后按顺序做就好,这样听说有7 ...
- 树状数组 && 线段树应用 -- 求逆序数
参考:算法学习(二)——树状数组求逆序数 .线段树或树状数组求逆序数(附例题) 应用树状数组 || 线段树求逆序数是一种很巧妙的技巧,这个技巧的关键在于如何把原来单纯的求区间和操作转换为 求小于等于a ...
- hdu1394(枚举/树状数组/线段树单点更新&区间求和)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题意:给出一个循环数组,求其逆序对最少为多少: 思路:对于逆序对: 交换两个相邻数,逆序数 +1 ...
- hdu 1166:敌兵布阵(树状数组 / 线段树,入门练习题)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- hdu 5147 Sequence II【树状数组/线段树】
Sequence IITime Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem ...
- 数据结构--树状数组&&线段树--基本操作
随笔目的:方便以后对树状数组(BIT)以及基本线段树的回顾 例题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 例题:hdu 1166 敌兵布阵 T ...
- BZOJ_1901_&_ZJU_2112_Dynamic_Rankings_(主席树+树状数组/线段树+(Treap/Splay))
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1901 给出一个长度为n的数列A,有m次询问,询问分两种:1.修改某一位置的值;2.求区间[l, ...
- BZOJ 3333 排队计划 树状数组+线段树
题目大意:给定一个序列.每次选择一个位置,把这个位置之后全部小于等于这个数的数抽出来,排序,再插回去,求每次操作后的逆序对数 首先我们每一次操作 对于这个位置前面的数 因为排序的数与前面的数位置关系不 ...
- 第十四个目标(dp + 树状数组 + 线段树)
Problem 2236 第十四个目标 Accept: 17 Submit: 35 Time Limit: 1000 mSec Memory Limit : 32768 KB Probl ...
- Curious Robin Hood(树状数组+线段树)
1112 - Curious Robin Hood PDF (English) Statistics Forum Time Limit: 1 second(s) Memory Limit: 64 ...
随机推荐
- Javascript中好用更改时间的方法
<script type="text/javascript"> //格式化时间格式的字符串 String.prototype.myTimes = function () ...
- 【2017-02-23】switch...case...和for循环
1.代码简化折叠: #region 标题 ... ... #endregion 一.switch...case... 1.格式 switch(变量){ case 值:代码段;break; case 值 ...
- 转 jquery怎么在header中设置请求信息
jquery是js的类库,js本身不能操作header,因为js是在浏览器加载页面过程中才开始执行的 header需要服务器端执行操作 如果是ajax,是可以设置header $.ajax({ url ...
- linux的文件权限小结
对于初接触Linux的朋友来说,会有各种不习惯和各种昏头,文件的权限就很让人不知所措. ls命令以及字段含义 比如我们列出当前目录文件: 我们来看下上述大致含义: 第1行显示的信息: 总用量(tota ...
- 【2-26】string/math/datetime类的定义及其应用
一string类 (1)字符串.Length Length作用于求字符串的长度,返回一个int值 (2)字符串.TrimStart(); TrimStart():可删除前空格,返回一个stri ...
- 对volatile关键字的理解
本文是基于对 http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html 这篇文档的理解 volatile 用volatile修饰的 ...
- ThinkPhp模板转Flask模板
Template Converter 网上的PHP资源很多,项目要用Python,所以想起做一个模板转换器,从ThinkPhp转成Flask的Jinja模板. 直接指定两个目录,将目录下的模板文件转换 ...
- KoaHub平台基于Node.js开发的Koa的简单包装到请求库的类似接口
co-request co-request promisify wrapper for request co-request Simple wrapper to the request library ...
- Spring之IOC详解
学过Spring的小伙伴对于IOC一定不陌生,IOC:控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spr ...
- 小命令tac、cat、rev的用法
cat:输出文件的内容(正序,由上至下) tac:输出文件的内容(倒序,由下至上) rev: 反转每行的文字内容,行号不变 示例:建立一个文件夹 1.演示cat效果 按原始样式正常显示 2.演示tac ...