树状数组模板及poj几道简单题

树状数组(入门附模板) 树状数组或二叉索引树(英语:Binary Indexed Tree),又以其发明者命名为Fenwick树,最早由Peter M. Fenwick于1994年以A New Data Structure for Cumulative Frequency Tables为题发表在SOFTWARE PRACTICE AND EXPERIENCE。其初衷是解决数据压缩里的累积频率(Cumulative Frequency)的计算问题,现多用于高效计算数列的前缀和, 区间和。——源自百度百科。 阅读详情

/*
觉得真是…经历了高考啥都忘了(其实还是当初学得不踏实
现在一点一点再重新来补吧(过了一年再来说这话的我
*/

参考资料及模板

http://blog.youkuaiyun.com/lawrence_jang/article/details/8054173 ——Lawrence_Jang
http://blog.youkuaiyun.com/qq_21841245/article/details/43956633 ——MoeO3

poj题目小集

poj 2352

看上去是个二维的题,事实上因为读入数据是按序排列的,所以可以直接转化成一维来做,就是个裸的单点修改区间查询的树状数组了。
也给了我们启示,有时对读入数据排序处理一下,就能收到很好的效果。
还有要注意的就是,树状数组维护的区间下标要从1开始,这道题WA了几次才注意到。

Code:

#include <cstdio>
#include <cstring>
#define maxn 32001
#define maxm 15010
inline int lowbit(int x) { return x & (-x); }
int n, level[maxm], c[maxn + 10];
void update(int x) {
    while (x <= maxn) {
        ++c[x];
        x += lowbit(x);
    }
}
int query(int x) {
    int ret = 0;
    while (x) {
        ret += c[x];
        x -= lowbit(x);
    }
    return ret;
}
void work() {
    memset(level, 0, sizeof(level));
    memset(c, 0, sizeof(c));
    for (int i = 0; i < n; ++i) {
        int x, y;
        scanf("%d%d", &x, &y);
        update(++x);
        ++level[query(x)];
    }
    for (int i = 1; i <= n; ++i) printf("%d\n", level[i]);
}
int main() {
    while (scanf("%d", &n) != EOF) work();
    return 0;
}

poj 2299 & poj 3067

两道用 树状数组 来解决 逆序对 的问题。
以前一直都只知道用归并来写的我实在是…个人觉得写起来比归并好写多了。
第一题就是裸的。
第二题还是先通过排序处理一下,做起来就方便不少。

poj 2299 Code:

#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 500010
using namespace std;
typedef long long LL;
struct node {
    int val, p;
    bool operator < (const node& nd) const { return val < nd.val; }
}a[maxn];
int b[maxn], c[maxn], n;
inline int lowbit(int x) { return x & (-x); }
int query(int x) {
    int ret = 0;
    while (x) {
        ret += c[x];
        x -= lowbit(x);
    }
    return ret;
}
void add(int x) {
    while (x <= n) {
//        printf("%d\n", x);
        ++c[x];
        x += lowbit(x);
    }
}
void work() {
    memset(c, 0, sizeof(c));
    for (int i = 1; i <= n; ++i) { scanf("%d", &a[i].val); a[i].p = i; }
    sort(a + 1, a + n + 1);
    for (int i = 1; i <= n; ++i) b[a[i].p] = i;
    LL sum = 0;
    for (int i = 1; i <= n; ++i) {
        sum += i - 1 - query(b[i]);
        add(b[i]);
    }
    printf("%lld\n", sum);
}
int main() {
    freopen("in.txt", "r", stdin);
    while (scanf("%d", &n) != EOF && n) work();
    return 0;
}

poj 3067 Code:

#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 1010
#define maxk 1000010
int c[maxn], kas, n, m, k;
using namespace std;
typedef long long LL;
struct Edge {
    int x, y;
}e[maxk];
bool cmp(Edge a, Edge b) {
    return a.x < b.x || (a.x == b.x && a.y < b.y);
}
inline int lowbit(int x) { return x & (-x); }
int query(int x) {
    int ret = 0;
    while (x) {
        ret += c[x];
        x -= lowbit(x);
    }
    return ret;
}
void add(int x) {
    while (x <= m) {
        ++c[x];
        x += lowbit(x);
    }
}
void work() {
    memset(c, 0, sizeof(c));
    scanf("%d%d%d", &n, &m, &k);
    for (int i = 0; i < k; ++i) scanf("%d%d", &e[i].x, &e[i].y);
    sort(e, e + k, cmp);
    LL sum = 0;
    for (int i = 0; i < k; ++i) {
        sum += i - query(e[i].y);
        add(e[i].y);
    }
    printf("Test case %d: %lld\n", ++kas, sum);
}
int main() {
    int T;
    scanf("%d", &T);
    while (T--) work();
    return 0;
}

poj 3928

要求一个序列中单调增或者单调减的三元组的个数总和。
写起来和逆序对差不多,从左起插一遍,右起插一遍,得到每个数左边比它大的、比它小的;右边比它大的、比它小的数的个数。其实就是枚举中间那个数,最后乘一乘就是答案。
这道题一个注意点就是题目中的 distinct integers,一开始没注意到,写得又稍微复杂了些,记录了每个数迄今出现的次数 cnt,然后再搞一搞啥的。其实也没啥…。

Code:

#include <cstdio>
#include <cstring>
#define maxn 100000
#define maxm 20010
int a[maxm], c[maxn + 10], cnt[maxn + 10], le1[maxm], le2[maxm], gr1[maxm], gr2[maxm];
typedef long long LL;
inline int lowbit(int x) { return x & (-x); }
void add(int x) {
    while (x <= maxn) {
        ++c[x];
        x += lowbit(x);
    }
}
int query(int x) {
    int ret = 0;
    while (x) {
        ret += c[x];
        x -= lowbit(x);
    }
    return ret;
}
void work() {
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
    memset(c, 0, sizeof(c));
    for (int i = 0; i < n; ++i) {
        int x = a[i];
        le1[i] = query(x);
        gr1[i] = i - le1[i];
        add(x);
    }
    memset(c, 0, sizeof(c));
    for (int i = n - 1; i >= 0; --i) {
        int x = a[i];
        le2[i] = query(x);
        gr2[i] = (n - 1 - i) - le2[i];
        add(x);
    }
//    for (int i = 1; i < n - 1; ++i) {
//        printf("%d %d %d %d\n", le1[i], le2[i], gr1[i], gr2[i]);
//    }
    LL ans = 0;
    for (int i = 1; i < n - 1; ++i) {
        ans += le1[i] * gr2[i] + le2[i] * gr1[i];
    }
    printf("%lld\n", ans);
}
int main() {
    freopen("in.txt", "r", stdin);
    int T;
    scanf("%d", &T);
    while (T--) work();
    return 0;
}

poj1195

裸的二维树状数组
一开始还是用while在那里写(太重的Pascal痕迹= =
后来看了模板改成优雅的for了…

Code:

#include <cstdio>
#include <cstring>
#define maxn 1030
int c[maxn][maxn], s, n;
inline int lowbit(int x) { return x & (-x); }
void update(int x, int y, int a) {
    for (int i = x; i <= n; i += lowbit(i)) {
        for (int j = y; j <= n; j += lowbit(j)) {
            c[i][j] += a;
        }
    }
}
int query(int x, int y) {
    if (x == 0 || y == 0) return 0;
    int ret = 0;
    for (int i = x; i; i -= lowbit(i)) {
        for (int j = y; j; j -= lowbit(j)) {
            ret += c[i][j];
        }
    }
    return ret;
}
void work() {
    memset(c, 0, sizeof(c));
    while (scanf("%d", &s)) {
        if (s == 3) return;
        if (s == 1) {
            int x, y, a;
            scanf("%d%d%d", &x, &y, &a);
            ++x; ++y;
            update(x, y, a);
        }
        else {
            int l, b, r, t;
            scanf("%d%d%d%d", &l, &b, &r, &t);
            ++r; ++t;
            printf("%d\n", query(r, t) - query(l, t) - query(r, b) + query(l, b));
        }
    }
}
int main() {
    freopen("in.txt", "r", stdin);
    while (scanf("%d%d", &s, &n) != EOF) work();
    return 0;
}
ACM竞赛全攻略:从知识体系到实战策略的备赛指南 算法与数据结构是计算机科学的核心基础,其原理在于通过高效的数据组织和计算步骤解决复杂问题。掌握这些核心技术能显著提升逻辑思维与问题解决能力,在软件开发、人工智能等领域具有极高价值。程序设计竞赛是检验与锤炼这些能力的经典应用场景,参与者需系统构建知识图谱,涵盖动态规划、图论、搜索等核心模块。本文聚焦于竞赛的完整生命周期,深入探讨如何通过专题训练与模拟实战进行有效备赛,并解析团队协作、时间管理及心态调整等关键实战策略,旨在帮助参赛者将知识转化为赛场上的实际竞争力。 阅读详情

相关推荐

树状数组 模版

标准的树状数组模版,查询,添加,修改都是O(logn)的时间复杂度,速度比SBT,和其他一些平衡树都快的多

树状数组模板

树状数组是一种可以高效处理前缀和的数据结构,相对于暴力解法的O(n)查询O(1)修改和朴素前缀和的O(1)查询和O(n)修改,它的查询和修改的时间复杂度都是O(logn),拥有总体对数时间复杂度的优异性能。在算法竞赛中,有时不使用线段树也能够使用树状数组来处理部分前缀和问题,毕竟敲一颗线段树还是略显臃肿。如图所示,相对于线段树的4*n的内存大小,树状数组的内存大小等同于原数组的大小n,因为每一层偶数个的不需要重复储存,因此节省了空间。

2401_87732330的博客 741

利用树莓派制作智能音箱

利用树莓派制作智能音箱

qq_61803022的博客 1777

树状数组&线段树模板

如题,已知一个数列,你需要进行下面两种操作:将某一个数加上x求出某区间每一个数的和输入格式第一行包含两个正整数nm,分别表示该数列数字的个数和操作的总个数。第二行包含n个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。接下来m行每行包含31 x k含义:将第x个数加上k2 x y含义:输出区间xy内每个数的和输出格式输出包含若干行整数,即为所有操作2的结果。样例 #1样例输入 #1样例输出 #11416提示【数据范围】对于30%的数据,1≤n。

m0_70897036的博客 1329

嵌入式Linux Qt应用程序卡死问题分析记录

根据应用和系统层面的分析,软件功能异常和卡死现象的原因是系统控制台/dev/console阻塞导致依赖其的相关应用和命令异常。系统控制台/dev/console阻塞的原因还未确定,最近的软件版本和其他测试同事未出现该问题,所以很大可能是串口线的问题,待后续有进展了继续更新。

V10_x的博客 1642

学术规范与论文写作(雨课堂)研究生 全部答案

1:如何造就优秀的学术论文 论文语法判断题 :全部是错的 2:如何撰写学术论文 3: SCI论文写作经验分享 4:论文写作与投稿技巧 5:学术伦理道德 答案仅供参考,研究生生活不易,大家如果有时间的话,还是可以学习学习的,毕竟老师讲的不错。加油,希望读研的每一个人都能顺利毕业! ...

Always-Learning 13万+

树状数组模板(C/C++)

注意:数组的长度不满足题意,仅提供模板!!

m0_71934846的博客 1156

Python爬虫-汽车之家各车系月销量榜数据

本文是该专栏的第41篇,后面会持续分享python爬虫干货知识。本文以某汽车平台为例,基于python采集该平台“各车系月销量”的榜单数据。具体实现思路和详细逻辑,笔者将在正文结合完整代码进行详细介绍。接下来,跟着笔者直接往下看正文详细内容。(附带完整代码)

Python进阶专栏《爬虫实战进阶》,《Pyppeteer从入门到精通》原创作者 1619

POJ 2299 离散化+树状数组

这段时间没怎么发博客 被动态规划折磨的头疼... 今天就把dp放下了 开始上手了几道树状数组的题 Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 60829   Accepted: 22563 Description

Frozensmile的博客 494

饥饿游戏搜索算法(HGS)详解:从生物激励到智能优化

饥饿游戏搜索算法(HGS)是一种受动物饥饿驱动觅食行为启发的智能优化算法。该算法通过模拟生物饥饿程度与觅食策略的关系,将个体适应度映射为饥饿感,并据此动态调整搜索行为。HGS的核心机制包括:1) 饥饿权重计算(W1/W2),2) 三种位置更新策略(随机探索、正向/负向协作),3) 自适应平衡参数E。算法通过迭代优化逐步改进解的质量,具有参数自适应、全局搜索能力强等特点,在复杂优化问题中表现出色。相比传统优化方法,HGS更注重个体内部状态对搜索行为的影响,实现了探索与开发的自然平衡。

qq_42212808的博客 155

【NodeRed】node-red-contrib-opcua实现PLC读写

在之前的博文【Node-RED】node-red-contrib-opcua-server模块使用(1)中,我们介绍了用node-red-contrib-opcua-server模块实现OPCUA服务端的,以及二次开发的内容。本节博文中我们采用官方社区自带的node-red-contrib-opcua组件开展对OPCUA客户端的介绍,详细阐述用该组件中OpcUa-Client节点实现客户端对PLC的读写,以及实现过程中遇到的问题。由于官方社区中并没有找到该组件的介绍实例,这也是本博文编写的第1个原因。

weixin_48618536的博客 958

第九届北航程序设计大赛网络预赛——水题题解

比赛链接:http://acm.buaa.edu.cn/contest/117/home/ 噩梦般的期末七连考刚刚过半,按现在的进度估计我cet6是要果考了,求过。。。。 本次比赛是复习期间断断续续做的,弱菜我冥思苦想只搞出6题,实在太弱……比赛结束后雷神告诉了我另外几道的思路,考完之后希望能有时间挑战下。 A BUAA 759 晴天小猪是点赞狂魔 题目链接:http://acm.buaa

whyorwhnt的专栏 1478

点云从入门到精通技术详解100篇-基于三维点云的机器人抓取位姿检测(续)

集到的深度信息会存在噪点,因此需要将生成的场景点云进行预处理,获得平滑、降采样处理场景点云,本文设计的预处理操作更能从冗杂的场景点云中提取清晰、平滑的目标点云,便于后续的抓取位姿采样,提高后续算法的处理效率。因此需要对场景点云进行适当的分割,仅保留目标物体的点云,整个过程可以通过。场较小时,空间中的点云密度会更加提高;觉子系统的效率,再保持全局点云几何形状不改变的前提下,通过对目标点云进行。体素降采样可以快速地减少点云数据并同时保持点云的形。个点,由于我们实施抓取的目标物体只占整个场景点云图的一部分,

getusushu的博客 773

2019年8月28日训练日记

今天把树状数组看完了,树状数组可以离线和在线两种方式处理数据,离线的话就是求区间最值或者前缀和,在线就是求逆序对这类问题,线段树看了几道题 以下是今天的题目: HDU 1556 树状数组 以前的树状数组是求前缀和,这次的树状数组是求操作次数,就是把前缀和变成操作次数和,每次操作+1 HDU 1394 树状数组求最小逆序数 知道第一次的逆序数用递推的方式就能求出剩下n-2次的逆序数 HDU ...

邵光亮的博客 796

Oracle EBS PAC定期成本分配处理程序请求报错:30011一个无效帐户与正在处理的物料关联

Oracle EBS版本: RDBMS : 12.1.0.2.0 Oracle Applications : 12.2.6 前提条件: 1、启用“MRP:调试模型”配置文件 月结会计反映执行《定期成本分配处理程序》请求报错: 中文:30011一个无效帐户与正在处理的物料关联。: CSTPALPC.create_dist_entry : 40 英文:30011An invalid account is associated with the item being transacted.:...

陈显平的专栏-Oracle EBS 1085

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

BUPT Spring Ranking Contest For 13 Round #3 DS

比赛地址:http://vjudge.net/contest/view.action?cid=47024#overview 这次的题目说难

Mr.Phoebe的专栏 1082

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

【Homework】LCA&RMQ

我校是神校,作业竟然选自POJ,难道不知道“珍爱生命 勿刷POJ”么? 所有注明模板题的我都十分傲娇地没有打,于是只打了6道题(其实模板题以前应该打过一部分但懒得找)(不过感觉我模板还是不够溜要找个时间刷一发)。 没注明模板题的都是傻逼题,其实也是模板题。 题目大致按照傻逼程度从大到小排序。 POJ 3264 Balanced Lineup 题意:n个数,m个询问,每次问max[...

weixin_30853329的博客 142

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

2017暑假集训总结 (17.7.9-)

【7.9】

Hi_jiaxinwei的博客 1019

2017.1其他简要题解

期末考试结束又到了做题的时候了 hdu5964 大胆推出公式,发现面积可以转换为两个互相独立的参数函数…… 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 typedef long long ll; 5 ll a,b,c,d; 6 ll mi,mx,x,y; 7 int main() ...

weixin_33725270的博客 108

暑期集训Day (20~24) 总结 (数据结构)

转眼间,暑期训练已经过了大半了。这半个多月以来也做了很多题,不过还是个菜鸡。。。 上一个专题是字符串专题,不过因为那个专题的题目没有写多少,所以。。。放到以后等做的题多一些再更新吧 这两天学数据结构确实收获不少,虽说之前对线段树,BIT这些早有耳闻,不过也仅仅是限于了解的层面,没有像最近几天系统的训练过。。。涨了很多姿势,不过题是做不完的QAQ。。。 Day 20 这一天的题还好没那么凶残...

star_moon0309的博客 361

算法竞赛省三无缘国赛:技术复盘与系统化训练指南

算法竞赛是检验编程与问题解决能力的重要平台,其核心在于对数据结构、算法原理的深入理解和高效应用。在ACM-ICPC、蓝桥杯等赛事中,参赛者需掌握动态规划、图论等关键技术,并通过系统训练提升编码准确性和调试效率,以应对复杂赛题。这些能力不仅在竞赛中决定排名,更是工程实践中解决实际问题的基石。本文聚焦于竞赛中常见的“临门一脚”场景,例如因罚时或解题数量等细微差距与晋级失之交臂,通过分析**调试效率**和**编码准确性**等关键热词,为选手提供从赛后复盘到能力补全的完整行动框架,帮助将比赛经验转化为可持续的技术成

weixin_34221036的博客 424

杭电“菜鸟杯”总结

12月18日,杭电菜鸟杯开赛。   这次学校的几个人没有集中比赛。jay回家了,在家里做。我在实验室一边。等到12点后才另有几个人过来,帮他们开了另一边的实验室。于是shadowright等就在另一边做了。还有其他的几个在宿舍做。   比赛开始后浏览了几道题,发现都是比较短的,难度还不是很确定,还没参加过菜鸟杯的比赛,老菜鸟杯的做过,自虐的那种。   于是看了第一题,粗略地写了一下,好像跟数

Human_CK的专栏 893

博文收藏

一些关于ACM的博文,有算法方面的,也有心得体会,大多读过但没能消化吸收。

whyorwhnt的专栏 6684

暑期集训Day (11,12,13,14) 总结(搜索进阶+DP进阶)

之前一直没写的搜索总结也留到今天写吧。。。 到目前为止,dp已经 复习了  预习了大部分内容,明天应该是最难的dp中的优化部分了,之前了解还不够深入。 个人理解,dp还是要多做题。有些dp还是很套路的,比如说区间dp和数位dp,基本上有板子可套。当然变化也是有的,这个时候就要具体题目具体分析了。。。 作为一个学习dp的菜鸡,这两题疯狂在补各种dp题,可是刷的dp题还是太少了。dp作为十分重要...

star_moon0309的博客 343
上一篇: 2017多校四 1004题 hdu 6070 Dirt Ratio 二分 + 线段树 + 分数规划
下一篇: poj 3321 Apple Tree 树状数组 dfs序
kkkkahlua
博客等级 码龄12年 4粉丝 116原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值