利用了二进制,二分的思想的一个很巧妙的数据结构,一个lowbit(x):二进制表示下的最右边的一个1开始对应的数值。

那么如果一个节点的为x左孩子,父亲节点就是 x + lowbit(x),如果是右孩子,父亲节点是 x-lowbit(x);

图中白条部分就是辅助数组C对应的最底下的和。

1、那么一个前缀和有是怎样的呢?

  就是从最底下开始,边往上走,边往左走。

2、修改单点呢?

  从最底下开始,边往上走,边往下走。

LA2191:

题目链接:https://vjudge.net/contest/147973#problem/A

题意:

先给出一个数组,然后有两个操作

S x y 把第x个数改成y

M x y计算x~y个数的和

Source Code:

 #include <bits/stdc++.h>

 using namespace std;

 inline int lowbit(int x)
{
return x&-x;
} struct FenwickTree
{
int n;
vector<int> C; void resize(int n)
{
this->n = n;
C.resize(n+);
}
void clear()
{
fill(C.begin(), C.end(), );
} // 计算A[1]+A[2]+...+A[x] (x<=n)
int sum(int x)
{
int ret = ;
while(x > )
{
ret += C[x];
x -= lowbit(x);
}
return ret;
} // A[x] += d (1<=x<=n)
void add(int x, int d)
{
while(x <= n)
{
C[x] += d;
x += lowbit(x);
}
}
}; FenwickTree f;
const int maxn = +;
int a[maxn]; int main()
{
// freopen("in.txt","r",stdin);
int n;
int cases = ;
while(scanf("%d",&n),n)
{
if(cases>) puts("");
printf("Case %d:\n",++cases);
f.resize(n);
f.clear();
for(int i=; i<=n; i++)
{
scanf("%d",&a[i]);
f.add(i,a[i]);
} char op[];
while(scanf("%s",op)!=EOF)
{
if(!strcmp(op,"END"))
break;
if(op[]=='M')
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",f.sum(y)-f.sum(x-));
}
if(op[]=='S')
{
int x,y;
scanf("%d%d",&x,&y);
int add = y - a[x];
a[x] = y;
f.add(x,add);
}
}
} return ;
}

LA5902:

题目链接:https://vjudge.net/contest/147973#problem/B

题意:

XXX喜欢看电影,他有好多好多的影碟,每个影碟都有个独立的编号。开始是从下往上影碟的顺序是n~1,他每次拿出影碟的时候,你需要输出压在该影碟上的有几个。(拿出后其他影碟顺序不变)看完影碟后,XXX会把影碟放在最上面。

分析:

把每个影碟放到一个考后的位置,这个位置有影碟,那么这里就是 1,否则是 0 ,每次询问,就是这个影碟所在的位置之前的前缀和,

把他放到前面去,当前位置置为 0 ,top 的位置 加 1,注意要记录每个影碟的所在位置。

Source Code:

 #include <bits/stdc++.h>

 using namespace std;

 inline int lowbit(int x)
{
return x&-x;
} struct FenwickTree
{
int n;
vector<int> C; void resize(int n)
{
this->n = n;
C.resize(n);
}
void clear()
{
fill(C.begin(), C.end(), );
} // 计算A[1]+A[2]+...+A[x] (x<=n)
int sum(int x)
{
int ret = ;
while(x > )
{
ret += C[x];
x -= lowbit(x);
}
return ret;
} // A[x] += d (1<=x<=n)
void add(int x, int d)
{
while(x <= n)
{
C[x] += d;
x += lowbit(x);
}
}
}; FenwickTree f;
const int maxn = +;
int pos[maxn]; int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int t;
scanf("%d",&t); while(t--)
{
int n,q;
scanf("%d%d",&n,&q);
f.resize(maxn*);
f.clear(); for(int i=; i<=n; i++)
{
f.add(maxn+i,);
pos[i] = maxn+i;
} int top = maxn;
while(q--)
{
int x;
scanf("%d",&x);
int tmp = pos[x];
if(q!=)
printf("%d ",f.sum(tmp-));
else printf("%d",f.sum(tmp-));
f.add(tmp,-);
f.add(top--,);
pos[x] = top + ;
}
puts("");
}
return ;
}

LA4329

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=26&page=show_problem&problem=2330

题意:

一条大街上住着n个乒乓球爱好者,经常组织比赛。每个人都有一个技能值ai,每场比赛需要3个人:两名选手和一名裁判。规定裁判位置必须在两个选手的中间,而且技能值也必须在两个选手的中间,问一共能组织多少种比赛。

分析:

和上题类似,每个技能值有的话为 1 ,否则为 0 ,每一个点都可以做裁判,那么他能组织多少场比赛?

a1~ai-1 有 ci个比 ai 小,ai+1~an有di个比他小,乘法加法原理,ci(n-i-di) + di(i-ci-1)。

 #include <bits/stdc++.h>

 using namespace std;

 inline int lowbit(int x) {
return x&-x;
} struct FenwickTree {
int n;
vector<int> C; void resize(int n) {
this->n = n;
C.resize(n);
} void clear() {
fill(C.begin(),C.end(),);
} //计算A[1] + A[2] + ... +A[n]
int sum(int x) {
int ret = ;
while(x>) {
ret +=C[x];
x -=lowbit(x);
}
return ret;
} // A[x] +=d;
void add(int x,int d) {
while(x<=n) {
C[x] +=d;
x +=lowbit(x);
}
}
}; const int maxn = + ;
int n;
int a[maxn];
FenwickTree f;
int c[maxn],d[maxn]; int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int maxa = ;
scanf("%d",&n);
for(int i=;i<=n;i++) {
scanf("%d",&a[i]);
maxa = max(maxa,a[i]);
} f.resize(maxa);
f.clear(); for(int i=;i<=n;i++) {
f.add(a[i],);
c[i] = f.sum(a[i]-);
} f.clear();
for(int i=n;i>=;i--) {
f.add(a[i],);
d[i] = f.sum(a[i]-);
} long long ans = ;
for(int i=;i<=n;i++) {
ans +=(long long)c[i]*(n-i-d[i]) + (long long)(i-c[i]-)*d[i];
}
printf("%lld\n",ans);
} return ;
}
												

二叉索引树,LA2191,LA5902,LA4329的更多相关文章

  1. 【转载】区间信息的维护与查询(一)——二叉索引树(Fenwick树、树状数组)

    在网上找到一篇非常不错的树状数组的博客,拿来转载,原文地址. 树状数组 最新看了一下区间的查询与修改的知识,最主要看到的是树状数组(BIT),以前感觉好高大上的东西,其实也不过就这么简单而已. 我们有 ...

  2. 二叉索引树BIT

    定义     二叉索引树,binary index tree,又名树状数组,或Fenwick Tree,因为本算法由Fenwick创造.     对于数组A,定义Query(i,j) = Ai +Ai ...

  3. C++实用数据结构:二叉索引树

    看下面这个问题(动态连续和查询): 有一个数组A(长度为n),要求进行两种操作: add(i,x):让Ai增大x: query(a,b):询问Aa+Aa+1+...+Ab的和: 若进行模拟,则每次qu ...

  4. POJ 3321 Apple Tree dfs+二叉索引树

    题目:http://poj.org/problem?id=3321 动态更新某个元素,并且求和,显然是二叉索引树,但是节点的标号不连续,二叉索引树必须是连续的,所以需要转化成连续的,多叉树的形状已经建 ...

  5. NYOJ 116 士兵杀敌(二)(二叉索引树)

    http://acm.nyist.net/JudgeOnline/problem.php?pid=116 题意: 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的. 小工是南将军手下的 ...

  6. HDU 1166 敌兵布阵(线段树 or 二叉索引树)

    http://acm.hdu.edu.cn/showproblem.php?pid=1166 题意:第一行一个整数T,表示有T组数据. 每组数据第一行一个正整数N(N<=50000),表示敌人有 ...

  7. 【树状数组(二叉索引树)】轻院热身—candy、NYOJ-116士兵杀敌(二)

    [概念] 转载连接:树状数组 讲的挺好. 这两题非常的相似,查询区间的累加和.更新结点.Add(x,d) 与 Query(L,R) 的操作 [题目链接:candy] 唉,也是现在才发现这题用了这个知识 ...

  8. 树状数组(二叉索引树 BIT Fenwick树) *【一维基础模板】(查询区间和+修改更新)

    刘汝佳:<训练指南>Page(194) #include <stdio.h> #include <string.h> #include <stdlib.h&g ...

  9. 1.红黑树和自平衡二叉(查找)树区别 2.红黑树与B树的区别

    1.红黑树和自平衡二叉(查找)树区别 1.红黑树放弃了追求完全平衡,追求大致平衡,在与平衡二叉树的时间复杂度相差不大的情况下,保证每次插入最多只需要三次旋转就能达到平衡,实现起来也更为简单. 2.平衡 ...

随机推荐

  1. vue中this.$router.push() 传参

    1  params 传参 注意⚠️:patams传参 ,路径不能使用path 只能使用name,不然获取不到传的数据 this.$router.push({name: 'dispatch', para ...

  2. Vue 参数传递及刷新后依旧存在

    获取参数方式有两种: 1.params2.query 第一种方式: params this.$router.push({name:'Hello',params:{name:'zs',age:'22'} ...

  3. 关于JAVA的基本知识

    TCP/IP 协议族常用协议 应用层:TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 等等 传输层:TCP,UDP 网络层:IP,ICMP,OSPF,EIGRP,IGMP 数据链 ...

  4. leetcode 620. Not Boring Movies 用where语句判断

    https://leetcode.com/problems/not-boring-movies/description/ 不管题目简不简单,现在先熟悉语法. 直接用where语句判断即可,判断奇偶可以 ...

  5. mysql-proxy读写分离,负载均衡

    配置mysql-proxy,创建主配置文件 cd /usr/local/mysql-proxy mkdir lua #创建脚本存放目录 mkdir logs #创建日志目录 cp share/doc/ ...

  6. SolrCloud的搭建的连接

    1 什么是SolrCloud SolrCloud(solr 云)是Solr提供的分布式搜索方案,当你需要大规模,容错,分布式索引和检索能力时使用SolrCloud.当一个系统的索引数据量少的时候是不需 ...

  7. 织梦dede模板中调用会员信息标签的方法

    织梦CMS v5.7调用文章所属会员信息标签 打开官方默认模板article_artcile.htm,我们可以提取出如下代码: {dede:memberinfos} 会员头像:<a href=& ...

  8. 百度网页分享js代码

    1.小图标 <div class="bdsharebuttonbox"> <a href="#" class="bds_qzone& ...

  9. Java反射机制分析指南

    一.JAVA是动态语言吗? 一般而言,说到动态言,都是指在程序运行时允许改变程序结构或者变量类型,从这个观点看,JAVA和C++一样,都不是动态语言. 但JAVA它却有着一个非常突出的动态相关机制:反 ...

  10. CentOS7中添加新硬盘

      cp /etc/fstab /etc/fstab.bak echo /dev/vdb1 /mnt/disk1 ext4 defaults 0 0 >> /etc/fstab mkdir ...