树状数组 && 线段树
树状数组
支持单点修改
#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 ...
随机推荐
- github学习(二)
Git学习(一) 学习github一定要学会git,否则在后续的github运用中会出现很多问题. 1.安装Git: Mac自带Git,Windows需要自己安装. 2.配置git: 配置user.n ...
- 利用instsrv和srvany来手动安装服务
Windows提供了两个小工具instsrv.exe和srvany.exe来把任何应用包装成windows服务.顾名思义instsrv(install service)是用来安装服务的,而srvany ...
- 数据库中的T-sql语句 条件修改 高级查询
1.创建数据库:create database --数据库名,不能中文,不能数字开头,不能符号开头 2.删除数据库:drop database-- 数据库名 use student--使用数据库 3. ...
- 1179: [Apio2009]Atm
1179: [Apio2009]Atm Time Limit: 15 Sec Memory Limit: 162 MBSubmit: 1629 Solved: 615[Submit][Status ...
- Node软件的安装
1.官网网址:https://nodejs.org/en/ 左边被推荐,右边最新 下载完成一键下一步直接安装,当然,如果你想修改安装目录的话当然没问题,注意:不要有英文目录 2.Window+r打开命 ...
- 文件上传组件FileUpload 以及邮箱搭建JavaMail
文件上传与下载 1.1 文件上传 案例: 注册表单/保存商品等相关模块! --à 注册选择头像 / 商品图片 (数据库:存储图片路径 / 图片保存到服务器中指定的目录) 文件上传,要点: 前台: 1 ...
- 内网转发ngrok的使用
1.下载解压ngrok:https://ngrok.com/download 2.执行ngrok会打开控制台 3.输入命令,开始映射本地的8080端口 ngork http 8080 控制台会返回一个 ...
- 关于jstl的问题:The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed
Current sofeware:java Eclipse ee 4.5.2 + Tomcat 6.0 Question: 在tomcat中部署好了我的项目,然后发布后没有报错.但是当在浏览器打开的时 ...
- java学习笔记 --- 面向对象
一.对象和类 类(class):类是用于描述现实事物的,它将现实事物进行抽象化,模板化描述.将事物的特点(属性)和行为封装在其中.比如小汽车的图纸,图纸就是小汽车的模版.图纸上画着小汽车的各种特点和功 ...
- 《InsideUE4》UObject(五)类型系统信息收集
在一起!在一起! 引言 前文中我们阐述了类型系统构建的第一个阶段:生成.UHT分析源码的宏标记并生成了包含程序元信息的代码,继而编译进程序,在程序启动的时候,开始启动类型系统的后续构建阶段.而本文我们 ...