樹狀數組三種模型

樹狀數組在區間求和問題上有大用,其三種復雜度都比線段樹要低很多……有關區間求和的問題主要有以下三個模型(以下設A[1..N]為一個長為N的序列,初始值為全0):

(1)“改點求段”型,即對于序列A有以下操作:

【1】修改操作:將A[x]的值加上c;

【2】求和操作:求此時A[l..r]的和。

這是最容易的模型,不需要任何輔助數組。樹狀數組中從x開始不斷減lowbit(x)(即x&(-x))可以得到整個[1..x]的和,而從x開始不斷加lowbit(x)則可以得到x的所有前趨。代碼:

void?ADD(int?x,?int?c)
{
?????for?(int?i=x;?i<=n;?i+=i&(-i))?a[i]?+=?c;
}
int?SUM(int?x)
{
????int?s?=?0;
????for?(int?i=x;?i>0;?i-=i&(-i))?s?+=?a[i];
????return?s;
}

?

操作【1】:ADD(x, c);

操作【2】:SUM(r)-SUM(l-1)。

(2)“改段求點”型,即對于序列A有以下操作:

【1】修改操作:將A[l..r]之間的全部元素值加上c;

【2】求和操作:求此時A[x]的值。

這個模型中需要設置一個輔助數組B:B[i]表示A[1..i]到目前為止共被整體加了多少(或者可以說成,到目前為止的所有ADD(i, c)操作中c的總和)。

則可以發現,對于之前的所有ADD(x, c)操作,當且僅當x>=i時,該操作會對A[i]的值造成影響(將A[i]加上c),又由于初始A[i]=0,所以有A[i] = B[i..N]之和!而ADD(i, c)(將A[1..i]整體加上c),將B[i]加上c即可——只要對B數組進行操作就行了。
【首先對于每個數A定義集合up(A)表示{A, A+lowestbit(A), A+lowestbit(A)+lowestbit(A+lowestbit(A))...} 定義集合down(A)表示{A, A-lowestbit(A), A-lowestbit(A)-lowestbit(A-lowestbit(A)) ... , 0}。可以發現對于任何A<B,up(A)和down(B)的交集有且僅有一個數。
翻轉一個區間[A,B](為了便于討論先把原問題降為一維的情況),我們可以把down(B)的所有元素的翻轉次數+1,再把down(A-1)的所有元素的翻轉次數-1。而每次查詢一個元素C時,只需要統計up(C)的所有元素的翻轉次數之和,即為C實際被翻轉的次數】

這樣就把該模型轉化成了“改點求點”型,只是有一點不同的是,SUM(x)不是求B[1..x]的和而是求B[x..N]的和,此時只需把ADD和SUM中的增減次序對調即可(模型1中是ADD加SUM減,這里是ADD減SUM加)。代碼:
void?ADD(int?x,?int?c)
{
?????for?(int?i=x;?i>0;?i-=i&(-i))?b[i]?+=?c;
}
int?SUM(int?x)
{
????int?s?=?0;
????for?(int?i=x;?i<=n;?i+=i&(-i))?s?+=?b[i];
????return?s;
}

操作【1】:ADD(l-1, -c); ADD(r, c);

操作【2】:SUM(x)。

(3)“改段求段”型,即對于序列A有以下操作:

【1】修改操作:將A[l..r]之間的全部元素值加上c;

【2】求和操作:求此時A[l..r]的和。

這是最復雜的模型,需要兩個輔助數組:B[i]表示A[1..i]到目前為止共被整體加了多少(和模型2中的一樣),C[i]表示A[1..i]到目前為止共被整體加了多少的總和(或者說,C[i]=B[i]*i)。

對于ADD(x, c),只要將B[x]加上c,同時C[x]加上c*x即可(根據C[x]和B[x]間的關系可得);

而ADD(x, c)操作是這樣影響A[1..i]的和的:若x<i,則會將A[1..i]的和加上x*c,否則(x>=i)會將A[1..i]的和加上i*c。也就是,A[1..i]之和 = B[i..N]之和 * i + C[1..i-1]之和。
這樣對于B和C兩個數組而言就變成了“改點求段”(不過B是求后綴和而C是求前綴和)。
另外,該模型中需要特別注意越界問題,即x=0時不能執行SUM_B操作和ADD_C操作!代碼:

void?ADD_B(int?x,?int?c)
{
?????for?(int?i=x;?i>0;?i-=i&(-i))?B[i]?+=?c;
}
void?ADD_C(int?x,?int?c)
{
?????for?(int?i=x;?i<=n;?i+=i&(-i))?C[i]?+=?x?*?c;
}
int?SUM_B(int?x)
{
????int?s?=?0;
????for?(int?i=x;?i<=n;?i+=i&(-i))?s?+=?B[i];
????return?s;
}
int?SUM_C(int?x)
{
????int?s?=?0;
????for?(int?i=x;?i>0;?i-=i&(-i))?s?+=?C[i];
????return?s;
}
inline?int?SUM(int?x)
{
????if?(x)?return?SUM_B(x)?*?x?+?SUM_C(x?-?1);?else?return?0;
}

操作【1】:
ADD_B(r, c); ADD_C(r, c);
if (l > 1) {ADD_B(l - 1, -c); ADD_C(l - 1, -c);}
操作【2】:SUM(r) - SUM(l - 1)。

轉載于:https://www.cnblogs.com/hujunzheng/articles/3968965.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/531672.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/531672.shtml
英文地址,請注明出處:http://en.pswp.cn/news/531672.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

php實現直播答題系統,直播答題解決方案

概述即構提供直播答題一站式解決方案&#xff0c;包括 Windows 主播端、移動 APP 端示例源代碼(iOS、Android)。1 下載/體驗地址由于直播答題場景需要主播端(推流、發題)和觀眾端(拉流、答題)配合使用&#xff0c;因此開發者需要同時下載這兩端的軟件。下載后&#xff0c;具體的…

poj 3486 A Simple Problem with Integers(樹狀數組第三種模板改段求段)

1 /*2 樹狀數組第三種模板&#xff08;改段求段&#xff09;不解釋&#xff01; 不明白的點這里&#xff1a;here&#xff01;3 */4 #include<iostream>5 #include<cstring>6 #include<cstdio>7 #include<algorithm>8 #define N 1000059 us…

php路由類默認模塊,微擎入口路由及其模塊入口路由 - YangJunwei

一、微擎入口路由微擎有2個入口文件/web/index.php?csite&aentry/app/index.php?centry路由變量$controller $_GPC[c]; //web入口缺省值account&#xff0c;app入口home$action $_GPC[a]; //index.php入口文件開頭$acl變量可配置默認方法$do $_GPC[do];不管$action是什…

matlab subs 慢,求助matlab程序計算速度過慢的原因

程序代碼如下function [length]contactlength(x0)if x0>50||x0error:數據超出尺寸范圍elsesyms xR300;%非球面頂點曲率半徑c1/R;delta0.1;k-3.3;%非球面參數rb27;%半徑y(-1*c*x.^2)./(1sqrt(1-(1k)*(c^2)*x.^2));dydiff(y);dy2diff(y,2);dyx0subs(dy,x0);dy2x0subs(dy2,x0);…

matlab r2010a教程,MATLAB教程R2010a(十二五)

第1章 基礎準備及入門1.1 MATLAB的安裝和工具包選擇1.2 Desktop操作桌面的啟動1.2.1 MATLAB的啟動1.2.2 Desktop操作桌面簡介1.3 Command Window運行入門1.3.1 Commancl Winelow指令窗簡介1.3.2 最簡單的計算器使用法1.3.3 數值、變量和表達式1.4 Command Window操作要旨1.4.1 …

java中解決組件重疊的問題(例如鼠標移動組件時)

java中解決組件覆蓋的問題&#xff01; 有時候在移動組件的時候會出現兩個組件覆蓋的情況&#xff0c;但是你想讓被覆蓋的組件顯示出來或者不被覆蓋&#xff01;在設計GUI時已經可以定義組件的疊放次序了&#xff08;按擺放組件的先后順序&#xff09;。 真正麻煩的是響應哪…

matlab橋梁受力計算公式,matlab橋梁計算

等級&#xff1a;文件 218KB格式 pdf內容簡介 該文結合斜拉橋施工監控的工程實踐&#xff0c;分析研究利用MATLAB 6&#xff0e;0神經網絡算法&#xff0c;可實現模式識別和函數逼近&#xff0c;進行信號處理&#xff0c;利用人工智能進行自動控制及非線性預測等。斜拉橋智能施…

php自然排序法的比較過程,PHP中strnatcmp()函數“自然排序算法”進行字符串比較用法分析(對比strcmp函數)...

本文實例講述了PHP中strnatcmp()函數“自然排序算法”進行字符串比較用法。分享給大家供大家參考&#xff0c;具體如下&#xff1a;PHP中strnatcmp()函數使用"自然"算法來比較兩個字符串(區分大小寫)&#xff0c;通常在自然算法中&#xff0c;數字 2 小于數字 10。而…

2014 網選 5014 Number Sequence(異或)

1 /*2 題意&#xff1a;a, b兩個序列&#xff0c;規定由[0, n]區間的數&#xff01;3 求 a[i] ^ b[i] 的和最大&#xff01; 4 5 思路&#xff1a;如果數字 n的二進制有x位&#xff0c; 那么一定存在一個數字m&#xff0c;使得n^m的所有二進制位6 都是1&am…

2014 網選 5007 Post Robot(暴力或者AC_自動機(有點小題大作了))

//暴力&#xff0c;從每一行的開始處開始尋找要查詢的字符 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std;char str[100005];int main(){while(gets(str)){for(int i0; str[i]; i)if(str[i]A){if(s…

java 如何放大動畫圖,Android仿微信圖片放大動畫

&#xff03;今年三月份直接上手做的android&#xff0c;代碼寫的不規范&#xff0c;有問題希望指出&#xff0c;謝謝(app數英)類似于微信 圖片瀏覽的效果&#xff0c;我的做法是在兩個activity A\B之間傳遞圖片的位置信息思路&#xff1a;在activity A的list view上有一張圖片…

2014 網選 5012 Dice(bfs模板)

1 /*2 題意&#xff1a;就是給定兩個篩子&#xff0c;每個篩子上6個面&#xff0c;每個面的數字屬于[1,6]&#xff0c; 且互不相同&#xff01;3 問a篩子最少經過按照題目規定的要求轉動&#xff0c;達到和b篩子上下左右前后的數字相同&#xff01;4 5 思路&am…

matlab 神經網絡dpi,基于DPI和BP神經網絡的P2P流量識別研究

研究與開發 現代計算機 2019.04 上 文章編號&#xff1a;1007-1423(2019)10-0031-05 DOI&#xff1a;10.3969/j.issn.1007-1423.2019.10.007 基于 DPI 和 BP 神經網絡的 P2P 流量識別研究 萬建偉&#xff0c;胡勇 (四川大學電子信息學院&#xff0c;成都 610021) 摘要&#xff…

2014 網選 5011 Game(Nim游戲,數學題)

/*題意&#xff1a;Nim游戲&#xff01; 思路&#xff1a;通過異或&#xff0c;判斷將n個數表示成二進制的形式之后&#xff0c;是否對應位的數字1 的個數是偶數&#xff01; */ #include<iostream> using namespace std;int main(){int n, x, s;while(cin>>n){s…

漢諾塔實踐python,Python練習題11:漢諾塔實踐

在終端輸出如下信息--python在終端輸出如下信息--python ???????????????????????????????????????????????????????????????????????????????????????????????? 描述 練習一…

oracle授權只讀用戶,Oracle創建只讀用戶(賬號)的方法

第一步&#xff1a;創建用戶(需要使用有dba管理員權限的用戶創建一個新的用戶&#xff0c;比如system)create user 用戶名 identified by 密碼 default tablespace 表空間;第二步&#xff1a;賦連接權限grant connect to 用戶名;grant Resource to 用戶名;權限分類&#xff1a;…

java中圖片文件的傳輸及顯示(Socket以及ServerSocket演示)

//客戶端部分 package testSix;import java.awt.Graphics; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; import java.util.Iterator;import javax.imageio.ImageIO; import …

oracle 表約束非空,oracle--約束(主鍵、非空、檢查)

問題1:學號重復了&#xff0c;數據還可以插入成功使用主鍵約束&#xff1a;學號是唯一標識一條數據的&#xff0c;所以必須唯一且不能為空---(1)、在確定為主鍵的字段后添加 primary key關鍵字---(2)、在創建表的后面使用&#xff1a;constraints pk_表名_字段名 primary key(字…

先序,中序,后序線索二叉樹

//后序線索&#xff0c;這種方法不容易想到 1 #include<iostream>2 #include<cstring>3 #include<cstdio>4 #include<algorithm>5 6 using namespace std;7 8 struct TREE{9 int val; 10 TREE *ch[2]; 11 TREE *thread;//該節點的線索的…

cdp備份適合oracle嗎,備份系統建設中的四個認識誤區,你有嗎?

【摘要】本文總結了企業在備份建設中常見的四個認識誤區。【作者】李志剛企業在備份建設中&#xff0c;主要的認識誤區有以下幾個&#xff1a;一、用雙機、陣列復制等系統冗余替代數據備份雙機雙柜可實現服務器和存儲的高可用性&#xff0c;保障業務持續運行&#xff0c;但絕不…