Color the ball----HDOJ1556
Color the ball
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6614 Accepted Submission(s): 3470
当N = 0,输入结束。
设想我们有这样一个问题:给定一个序列,A1,A2,A3........An,现在需要频繁的查询区间(i,j)里面所有元素的和,而且这个序列中的元素是变化的。当然我们可以用最简单的暴力法,一个个加呗,这样时间复杂度为O(n),插入数据时间复杂度是O(1)的,更新是O(m),这样一来总的时间复杂度会是O(n×m),数据一旦变大,效率太低,此时就要用树状数组,也叫作二叉搜索树(Binary Indexed Trees)BIT。
它基于这样一个定义:令数组C[i] = A[i-2^k+1]+...+A[i],这样以来C[i]表示的就是区间(i-2^k+1,i)的和,这里k表示的是:i对应的二进制数末尾连续0的个数,比如8(10) = 1000(2),那么k = 3;它所维护的区间是不是很“晦涩”,不知道他是怎么想得,据说Peter M. Fenwick的这样定义的思路来源于二进制思想。我个人认为这是整个树状数组最有价值的部分,也是最值得研究的部分。
1,基于这样一个定义我们的问题来了,对于确定的i,如何计算k的值?换句话说我们要知道2^k的值,再换句话说就是计算二进制位中最右边那个1的位权,不然一切都不用谈了,没意义。而且要高效,其实可以利用C语言位运算来做(用的很巧妙):
我们可以这样表示一个二进制数:a1b,这里b都是0(0的个数可以是0),a任意,但必须保证1是最右边的那个1,例如 14(10) = 1100(2),那么a=1,b=00,
那么-a1b在计算机里是以补码表示的,即反码加1,我把它记为(a-)0(b-)+1,所以(b-)全为1了,所以(a-)0(b-)+1 = (a-)0(1...1)+1 = (a-)1(0...0), 它再与a1b按为与运算,a1b & (a-)1(0...0) = (0...0)1(0...0),这样就得到了2^k的值了,很神奇!
写个函数就是:
1 int LowBit(int t) 2 { 3 return t & (-t); 4 }
我们就把第一个问题解决了!
这个函数的功能就是寻找当前节点的父节点或者子节点!!!
2,那么我们如何来计算C[i]的值?就是说我们插入数据A[j]的时候如何来更新C[i]?我们不光要更新C[i],而且还要更新与A[j]有关的其他的C[k1]...C[kn],这样才能保证C[i]维护的值是正确的。
先来个图吧,这样看得明白。
1 void update(int pos,int val) 2 { 3 while(pos <= n) 4 { 5 c[pos] += val; 6 pos += LowBit(pos); 7 } 8 return ; 9 }
3,如何得到某个区间(i,j)的和呢?
我们高中就学过sum(i) = A1+A2+A3+...+Ai;
sum(j) = A1+A2+A3+...+Aj;
那么sum(i->j)= sum(j)-sum(i);
现在问题又来了,怎么知道sum(n)的值的?
我们把1。。。n所包含的子区间的和加一起就可以了,现在关键是如何找区间了,比如给你13,让你求sum(13),怎么找13的子区间?这还得根据LowBit()函数的计算过程来逆退,刚才不是update函数是加得到的父区间,现在逆过来就减!函数如下:
1 void Get_Result(int pos) 2 { 3 while(pos > 0) 4 { 5 sum += c[pos]; 6 pos -= LowBit(pos); 7 } 8 return ; 9 }
三个函数都很简洁,代码比较简单,但思想绝不简单!特别是那个定义!
对于数状数组我今天就理解这么多,以得还的进一步理解。
AC代码:
1 #include<stdio.h> 2 #include<string.h> 3 #define MAX 100005 4 int c[MAX]; 5 int sum,n; 6 int LowBit(int t) 7 { 8 return t & (-t); 9 } 10 11 void update(int pos,int val) 12 { 13 while(pos <= n) 14 { 15 c[pos] += val; 16 pos += LowBit(pos); 17 } 18 return ; 19 } 20 21 void Get_Result(int pos) 22 { 23 while(pos > 0) 24 { 25 sum += c[pos]; 26 pos -= LowBit(pos); 27 } 28 return ; 29 } 30 31 int main() 32 { 33 int a,b,i; 34 while(~scanf("%d",&n) && n) 35 { 36 memset(c,0,sizeof(c)); 37 for(i = 1;i <= n;i ++) 38 { 39 scanf("%d%d",&a,&b); 40 update(a,1); 41 update(b+1,-1); 42 } 43 for(i = 1;i < n;i ++) 44 { 45 sum = 0; 46 Get_Result(i); 47 printf("%d ",sum); 48 } 49 sum = 0; 50 Get_Result(i); 51 printf("%d\n",sum); 52 } 53 return 0; 54 }
转载于:https://www.cnblogs.com/wangzhili/p/3950353.html
Color the ball----HDOJ1556相关推荐
- hdu 1556 Color the ball
Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- Color the ball
Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- hdu 1556:Color the ball(第二类树状数组 —— 区间更新,点求和)
Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- HDU 1556 Color the ball (数状数组)
Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- 杭电1556 Color the ball
Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- Color the ball(树状数组区间更新+单点求值)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1556 Color the ball Time Limit: 9000/3000 MS (Java/Ot ...
- HDU1556 Color the ball【差分数组+线段树】
Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- HDU1556 Color the ball(树状数组+抖机灵)
题目: Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- HDU-1199 color the ball
唉!这题完全没必要用线段树,用一个很常规的方法就可以过了. 不解释,常规方法就A了. #include<stdio.h> #include<string.h> int q[10 ...
- Color the ball(HDU1556)树状数组
每次对区间内气球进行一次染色,求n次操作后后所有气球染色次数. 树状数组,上下区间更新都可以,差别不大. 1.对于[x,y]区间,对第x-1位减1,第y位加1,之后向上统计 #include<b ...
最新文章
- python零基础怎么学-零基础如何入门Python
- vtigercrm安装
- C++ 标准模板库(STL)
- php系统毕设答辩问题,计算机专业毕业论文答辩的一般程序及常见问题
- 嵌入式科普:基本概念,设计流程,开发特点,如何学习
- 【强化学习】MOVE37-Introduction(导论)/马尔科夫链/马尔科夫决策过程
- Android 号码, 来电归属地 Jni 使用C++对二进制文件查询(一) 理论篇
- C 标准库 —— ctypes.h
- 2021年全球与中国飞机飞行控制系统(FCS)行业市场规模现状及企业市场份额分析
- mac os 系统word文档批量更改图片尺寸问题汇总
- winpe 能否修复服务器系统盘,U盘WINPE、光盘WINPE系统(启动修复盘)制作图文教程...
- vmware虚拟机网络设置方法(轻松版)
- 升入高中,如何规划数学竞赛
- 计算机学报在线阅读,计算机学报CHIN.pdf
- 目前上海最便宜的企业宽带-199元的旺铺通B1套餐
- 2022~2023计算机毕业设计选题篇-选题推荐
- Win10家庭版 误删winsock和winsock2注册表的解决方案
- 牛人面试时英文自我介绍
- ESP8266制作天气预报海藻球微景观生态缸记录(二)-人体感应开关灯实现
- VisualStudio2022编译FreeCAD-0.20.2
热门文章
- 未来,谁来为AI开源买单?科技圈顶级码农是这样看的 | CCF C³-04@百度
- 李飞飞团队从动物身上get AI新思路,提出RL计算框架,让机器在复杂环境学习和进化...
- 小米做手机是真不赚钱,米粉要支持请多容忍广告
- 一张照片生成积木的你!5个在校生2个月做的AI项目,李开复看了赞不绝口
- 湖大深大A级学科数超南开,华科文科胜过武大!泰晤士的首份高校评级结果,让人有点方...
- 造假露馅!曾创下融资纪录的科技公司,被曝用印度码农冒充AI,挣了1个多亿...
- springCloud-4.RestTemplat的使用(两个client之间的调用)
- 双十一电商江湖:唯品会与天猫发力“天团“
- CoreOS的Tectonic新发行版支持Kubernetes自我管理
- C++ const与define