树状数组

支持单点修改

#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]维护序列的题解

树状数组 && 线段树的更多相关文章

  1. 洛谷P2414 阿狸的打字机 [NOI2011] AC自动机+树状数组/线段树

    正解:AC自动机+树状数组/线段树 解题报告: 传送门! 这道题,首先想到暴力思路还是不难的,首先看到y有那么多个,菜鸡如我还不怎么会可持久化之类的,那就直接排个序什么的然后按顺序做就好,这样听说有7 ...

  2. 树状数组 && 线段树应用 -- 求逆序数

    参考:算法学习(二)——树状数组求逆序数 .线段树或树状数组求逆序数(附例题) 应用树状数组 || 线段树求逆序数是一种很巧妙的技巧,这个技巧的关键在于如何把原来单纯的求区间和操作转换为 求小于等于a ...

  3. hdu1394(枚举/树状数组/线段树单点更新&区间求和)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题意:给出一个循环数组,求其逆序对最少为多少: 思路:对于逆序对: 交换两个相邻数,逆序数 +1 ...

  4. hdu 1166:敌兵布阵(树状数组 / 线段树,入门练习题)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  5. hdu 5147 Sequence II【树状数组/线段树】

    Sequence IITime Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem ...

  6. 数据结构--树状数组&&线段树--基本操作

    随笔目的:方便以后对树状数组(BIT)以及基本线段树的回顾 例题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 例题:hdu 1166 敌兵布阵 T ...

  7. BZOJ_1901_&_ZJU_2112_Dynamic_Rankings_(主席树+树状数组/线段树+(Treap/Splay))

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1901 给出一个长度为n的数列A,有m次询问,询问分两种:1.修改某一位置的值;2.求区间[l, ...

  8. BZOJ 3333 排队计划 树状数组+线段树

    题目大意:给定一个序列.每次选择一个位置,把这个位置之后全部小于等于这个数的数抽出来,排序,再插回去,求每次操作后的逆序对数 首先我们每一次操作 对于这个位置前面的数 因为排序的数与前面的数位置关系不 ...

  9. 第十四个目标(dp + 树状数组 + 线段树)

    Problem 2236 第十四个目标 Accept: 17    Submit: 35 Time Limit: 1000 mSec    Memory Limit : 32768 KB  Probl ...

  10. Curious Robin Hood(树状数组+线段树)

    1112 - Curious Robin Hood    PDF (English) Statistics Forum Time Limit: 1 second(s) Memory Limit: 64 ...

随机推荐

  1. Spring_构造注入

    依赖注入的第二种注入方式:构造器注入 创建带参数的构造方法,参数类型为注入类的类型 项目要先添加spring支持: package com; public class Computer { priva ...

  2. 关于java socket

    1. 关于new Socket()中参数的理解 Server端: 调用ServerSocket serverSocket = new ServerSocket(1287,2);后Server端打开了指 ...

  3. Struts2之Result详解

    上一篇我们把Struts2中的Action接收参数的内容为大家介绍了,本篇我们就一起来简单学习一下Action的4种Result type类型,分为:dispatcher(服务端页面跳转):redir ...

  4. 转换器4:手写PHP转Python编译器,语法解析部分

    写完词法部分,又有很多杂事,周末终于有空来实现伟大的语法解析部分了. 撸完代码之后发现,程序太短了,不算上状态机,才186行(含注释),关键代码不到100行.运行调试过后,发现还行.居然可以解析One ...

  5. 算法模板——LCA(最近公共祖先)

    实现的功能如下——在一个N个点的无环图中,共有N-1条边,M个访问中每次询问两个点的距离 原理——既然N个点,N-1条边,则说明这是一棵树,而且联通.所以以1为根节点DFS建树,然后通过求两点的LCA ...

  6. (1)写给Web初学者的教案-----学习Web的知识架构

    1:学习Web的知识架构 前文中我们简单的介绍了一些关于Web的基本知识,这里任老师再次强调一下凡是用浏览器打开的网站我们就称之为Web应用程序(B/S结构).除此之外其它需要下载安装的软件或是手机  ...

  7. SEO-友情链接注意事项

    为什么要专门给友链一个区域呢?由此就可以想象到友情链接对一个网站有多重要前期,网站没有权重的时候,跟别人换友链,人家基本是不会换的因为你网站没权重,加了友链他也获取不到权重,对网站没有多少好处一般我们 ...

  8. 关于极光推送在手机系统低于iOS10的手机上闪退的问题。

    最近项目中用到了极光推送,升级到了最新的SDK 2.1.9版本,发现只能在iOS10 上运行,其他测试的时候真机闪退.贴上一个可能的原因:

  9. SQL函数和SQL Server2008

    1.绝对值   SQL:select abs(-1) value  O:select abs(-1) value from dual  2.取整(大)   S:select ceiling(-1.00 ...

  10. Java基础之路(四)--流程控制语句

    本次我们来聊一聊Java当中的循环语句. 循环语句分三种:1.for2.while3.do--while. 三种循环语句的任务是不同的,方法也是不同的.当然他们各自的流程图也是不一样的. 3.1 wh ...