树状数组

树状数组-蓝桥杯省赛C++B组-小朋友排队

寵の児 提交于 2020-02-27 23:53:32
树状数组-蓝桥杯省赛C++B组-小朋友排队 题目: n 个小朋友站成一排。 现在要把他们按身高从低到高的顺序排列,但是每次只能交换位置相邻的两个小朋友。 每个小朋友都有一个不高兴的程度。 开始的时候,所有小朋友的不高兴程度都是 0。 如果某个小朋友第一次被要求交换,则他的不高兴程度增加 1,如果第二次要求他交换,则他的不高兴程度增加 2(即不高兴程度为 3),依次类推。当要求某个小朋友第 k 次交换时,他的不高兴程度增加 k。 请问,要让所有小朋友按从低到高排队,他们的不高兴程度之和最小是多少。 如果有两个小朋友身高一样,则他们谁站在谁前面是没有关系的。 输入格式 输入的第一行包含一个整数 n,表示小朋友的个数。 第二行包含 n 个整数 H1,H2,…,Hn,分别表示每个小朋友的身高。 输出格式 输出一行,包含一个整数,表示小朋友的不高兴程度和的最小值。 数据范围 1≤n≤100000, 0≤Hi≤1000000 输入样例: 3 3 2 1 输出样例: 9 样例解释 首先交换身高为3和2的小朋友,再交换身高为3和1的小朋友,再交换身高为2和1的小朋友,每个小朋友的不高兴程度都是3,总和为9。 题解: 过 程 类 似 于 冒 泡 排 序 , 对 于 n 个 无 序 数 , 通 过 相 邻 两 项 交 换 得 到 有 序 序 列 , 每 一 个 数 h [ i ] 需 要 交 换 的

PAT-1057. Stack (30)--树状数组

荒凉一梦 提交于 2020-02-27 03:24:28
今天新学了一个知识,叫做线状数组,主要应用领域 1,数据频繁更新 2,求解某一段区间的和 以上产景情况下可以使用线状数组,更新某一个数据和求某一段时间之和时间复杂度都是Log(N) {常规情况是O(1)和O(N)} 线状数组和RMQ差不多,都可以再Log(N)时间复杂度内求解某一段区间的长度,线状数组额实现方式更为简单,更为方便 以下可以当做线段树的模板 主要函数有lowbit给定制定数字二进制下在末尾为0的个数。 Update更新某一节点的值。 getsum求解某一区间的值 Update是从叶子到根顶部跟新,getsum是从上至下更新,父子节点的差距就是lowbit(n); 求解一段区间的和为什么可以用来求解中位数呢? 声明数组,初始化为0,当某个数出现的时候,比如10,那么tree[10]=1; 比如查找1-100就可以知道100以内有多少个数据存在了。 有一个问题比如 1 2 3 4 5 6 7 8 9 10 0 0 0 1 0 0 1 0 1 0 那么求解1-4的和为1 求解1-5也为1,求解1-6也为1.那么我怎么知道是哪一个作为? (编码的时候只有当l==r时候才返回值,也就是区间左右都相等的时候才返回值,否则不返回值,如果是getsum(mid)==mid不做特殊处理。最初写成返回return mid 还是树状数组理解不够深。。待续。。。 ) // 1057.cpp

树状数组的整理

依然范特西╮ 提交于 2020-02-27 02:53:43
* 如m = 11000, 则C[m] = C[10100] + C[10110] + C[10111] + A[11000]; 则S[m] = C[11000] + C[10000]; 1.区间求和 向上更新每一个父节点,向下统计每一个子节点之和; 2.查询单点 向上更新区间(update(l,1) /*以左端点为起点++*/ ,update(r+1,-1) /*以右端点为起--*/ ),向下统计子节点之和; 反过来,向下更新向上统计也可以; * 1.树状数组的起点从1开始,到最大值结束,因此终点n不是个数而是最大值; 2.空间复杂度为N,即数组大小为N; 代码模版: void update(int pos,int val) { while(pos <= n) { c[pos] += val; pos += lowbit(pos); } } int sum(int end) { int ret = 0; while(end > 0) { ret += c[end]; end -= lowbit(end); } return ret; } 3.求逆序数   对于一个序列求每个数前面比它大或小的数的个数的总和,将数字离散化得到大小关系用树状数组求和;    /*离散化:当数据只与它们之间的相对大小有关,而与具体是多少无关时,可以进行离散化。*/ 代码模版:    for(int i

[树状数组&离散化] CF 1311 F

落花浮王杯 提交于 2020-02-26 23:10:58
题目 思路 数据比较大,先离散化。 可以先把x sort一遍通过v找出答案 如果x由小到大,前面v比当前V小d(i,j)=xi-xj;否则为0 i时前面所有的d为 比现在小的点数目*a[i].x-比现在小的点的距离和 代码 # include <cstdio> # include <cstring> # include <cmath> # include <cstdlib> # include <cctype> # include <ctime> # include <iostream> # include <string> # include <map> # include <queue> # include <stack> # include <set> # include <vector> # include <iomanip> # include <list> # include <bitset> # include <sstream> # include <fstream> # include <complex> # include <algorithm> # if __cplusplus >= 201103L # include <unordered_map> # include <unordered_set> # endif # define ll long long

Moving Points(树状数组)

两盒软妹~` 提交于 2020-02-25 19:58:05
There are n points on a coordinate axis OX. The i-th point is located at the integer point xi and has a speed vi. It is guaranteed that no two points occupy the same coordinate. All n points move with the constant speed, the coordinate of the i-th point at the moment t (t can be non-integer) is calculated as xi+t⋅vi. Consider two points i and j. Let d(i,j) be the minimum possible distance between these two points over any possible moments of time (even non-integer). It means that if two points i and j coincide at some moment, the value d(i,j) will be 0. Your task is to calculate the value ∑1≤i

树状数组区间修改加区间查询 Acwing 243. 一个简单的整数问题2

可紊 提交于 2020-02-23 04:10:10
参考博客: https://www.cnblogs.com/lcf-2000/p/5866170.html 原题: https://www.acwing.com/problem/content/description/244/ 给定一个长度为N的数列A,以及M条指令,每条指令可能是以下两种之一: 1、“C l r d”,表示把 A[l],A[l+1],…,A[r] 都加上 d。 2、“Q l r”,表示询问 数列中第 l~r 个数的和。 对于每个询问,输出一个整数表示答案。 输入格式 第一行两个整数N,M。 第二行N个整数A[i]。 接下来M行表示M条指令,每条指令的格式如题目描述所示。 输出格式 对于每个询问,输出一个整数表示答案。 每个答案占一行。 数据范围 1≤N,M≤1051≤N,M≤105, |d|≤10000|d|≤10000, |A[i]|≤1000000000|A[i]|≤1000000000 输入样例: 10 5 1 2 3 4 5 6 7 8 9 10 Q 4 4 Q 1 10 Q 2 4 C 3 6 3 Q 2 4 输出样例: 4 55 9 15 时/空限制: 1s / 64MB #include<iostream> #define ll long long using namespace std; const int N = 100000 + 10; ll

#树状数组,线段树,离散#JZOJ 3854 分组 From 2020.01.16【NOIP提高组】模拟A 组

廉价感情. 提交于 2020-02-15 19:16:53
题目 Bsny所在的精灵社区有 \(n\) 个居民,每个居民有一定的地位和年龄, \(r_i\) 表示第 \(i\) 个人的地位, \(a_i\) 表示第 \(i\) 个人的年龄。 最近社区里要举行活动,要求几个人分成一个小组,小组中必须要有一个队长,要成为队长有这样的条件: 1、队长在小组中的地位应该是最高的(可以并列第一); 2、小组中其他成员的年龄和队长的年龄差距不能超过 \(K\) 。 有些人想和自己亲密的人组在同一个小组,同时希望所在的小组人越多越好。比如 \(x\) 和 \(y\) 想在同一个小组,同时希望它们所在的小组人越多越好,当然,它们也必须选一个符合上述要求的队长,那么问你,要同时包含 \(x\) 和 \(y\) 的小组,最多可以组多少人? 第一行两个整数 \(n\) 和 \(K\) ; 接下来一行输入 \(n\) 个整数: \(r_1, r_2,\dots, r_n\) 接下来一行输入 \(n\) 个整数: \(a_1, a_2,\dots, a_n\) 接下来输入 \(Q\) 表示有 \(Q\) 个询问; 接下来 \(Q\) 行每行输入 \(x, y\) ,表示询问:当 \(x\) 和 \(y\) 组在同一个小组,它们小组最多可以有多少人( \(x\) 和 \(y\) 也有可能被选为队长,只要它们符合条件)。 对于每个询问,输出相应的答案,每个答案占一行。

敌兵布阵 (树状数组&线段树入门)

我只是一个虾纸丫 提交于 2020-02-15 16:54:34
C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了。A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况。由于采取了某种先进的监测手段,所以每个工兵营地的人数C国都掌握的一清二楚,每个工兵营地的人数都有可能发生变动,可能增加或减少若干人手,但这些都逃不过C国的监视。 中央情报局要研究敌人究竟演习什么战术,所以Tidy要随时向Derek汇报某一段连续的工兵营地一共有多少人,例如Derek问:“Tidy,马上汇报第3个营地到第10个营地共有多少人!”Tidy就要马上开始计算这一段的总人数并汇报。但敌兵营地的人数经常变动,而Derek每次询问的段都不一样,所以Tidy不得不每次都一个一个营地的去数,很快就精疲力尽了,Derek对Tidy的计算速度越来越不满:"你个死肥仔,算得这么慢,我炒你鱿鱼!”Tidy想:“你自己来算算看,这可真是一项累人的工作!我恨不得你炒我鱿鱼呢!”无奈之下,Tidy只好打电话向计算机专家Windbreaker求救,Windbreaker说:“死肥仔,叫你平时做多点acm题和看多点算法书,现在尝到苦果了吧!”Tidy说:"我知错了。。。"但Windbreaker已经挂掉电话了。Tidy很苦恼,这么算他真的会崩溃的,聪明的读者,你能写个程序帮他完成这项工作吗

hdu1166(树状数组)

∥☆過路亽.° 提交于 2020-02-15 16:04:48
敌兵布阵 题意:   第一行一个整数T,表示有T组数据。每组数据第一行一个正整数N(N<=50000),表示敌人有N个工兵营地,接下来有N个正整数,第i个正整数ai代表第i个工兵营地里开始时有ai个人(1<=ai<=50)。接下来每行有一条命令,命令有4种形式: (1) Add i j,i和j为正整数,表示第i个营地增加j个人(j不超过30) (2)Sub i j ,i和j为正整数,表示第i个营地减少j个人(j不超过30); (3)Query i j ,i和j为正整数,i<=j,表示询问第i到第j个营地的总人数; (4)End 表示结束,这条命令在每组数据最后出现; 分析:   线段树和树状数组的模板题。 代码: #include <map> #include <queue> #include <vector> #include <math.h> #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; #define ll long long #define ull unsigned long long #define cls(x) memset(x,0,sizeof(x)) #define clslow(x) memset(x,-1