財神娛樂首存即享優惠回饋唷~詳情請進👉

『數據運彩棒球布局』樹狀數組

樹狀數組的成績模子:

目前有一個如許的成績:

有一個數組\(a\),下標從\(0\)到\(n-1\),目前你要進行\(w\)次點竄,\(q\)次查問。
點竄是點竄數組中某一個元素的值;
查問是查問數組中恣意一個區間的以及,\(w+q<500000\)。
這個成績很廣泛,起首闡發下質樸做法的時間龐大度,
點竄是\六合彩即時(O(1)\)的時間龐大度,
而查問就要\(O(n^2)\)的龐大度,總體時間龐大度為\(O(q*q*n*n)\);
你或者許會想到用前綴以及來優化這個查問,
咱們再來闡發下,查問的話是\(O(1)\)的龐大度,
然則點竄的時辰點竄一個點,那末在以后的一切前綴以及都要更新,
以是點竄的時間龐大度是\(O(n^2)\),總體時間龐大度仍是\(O(q*q*n*n)\)。
可以發明,兩種做法中,要末查問是\(O(1)\),點竄是\(O(n^2)\);
要末點竄是\(O(1)\),查問是\(O(n^2)\)。
有無一種做法可以下降時間龐大度呢?樹狀數組。
咱們先來相識下\(lowbit\)這個函數,
你也先不要問這個函數到底在樹狀數組中有甚么用;
\(lowbit\)這個函數的功效便是求某一個數的二進制透露表現中最低的一名1,

\(for\) \(example\),\(x=6\),它的二進制為\(110\),
那末\(lowbit(x)\)就返歸\(2\),由于最初一名\(1\)透露表現\(2\)。
咱們怎么求\(lowbit\)呢?

求正數的補碼的簡便要領:

先把這個數的二進制寫進去,然后從右向左找到第一個\(1\),這電競下注個\(1\)不要動以及這個\(1\)右側的二進制不變,左側的二進制依次取反,如許就求出的一個數的補碼,說這個要領首要是讓咱們懂得一個正數的補碼在二進制上的特性,然后咱們把這個正數對應的負數與該正數與運算一下,因為這個\(1\)的左側的二進制與負數的原碼對應的部門是相反的,以是相與肯定都為\(0\),因為這個\(1\)以及這個\(1\)右側的二進制都是不變的,是以,相與后仍是原來的模樣,

以是,這個得出的效果便是\(lowbit(x)\)的效果。

lowbit函數:

int lowbit(x) 
{   
    return x & -x;
}

二進制的視角:一個數\(n\),假定\(n=6\),它的二進制為\(110\),咱們把它透露表現成累加的情勢\(110=100+10\),如許是可以的,那末咱們要求前\(6(110)\)項的以及可以如許求:

\(∑i=16=(a[1]+a[2]+a[3]+a[4])+(a[5]+a[6])\)

注重括號中的元素個數,
是否是\(4(100)\)個加\(2(算偏財運10)\)個,
以及\(110=100+10\)是否是很像,
\(10\)便是\(lowbit(110)\)的效果,\(100\)是\(lowbit(100)\)的效果。
乞降的時辰咱們老是把\(∑ni=1\)以及\(∑i=1n\)拆分紅如許的幾段區間以及來計算,
區間的出發點以及長度便是依據\(n\)的二進制來的,
二進制怎么拆的,你就怎么拆分,而拆分二進制就要用到下面說的\(lowbit\)函數了。
這里也能夠瓜熟蒂落得給出\(c\)數組的透露表現了。
\(c[i]\)透露表現從第i個元素向前數\(lowbit(i)\)個元素,這一段的以及,這便是下面說的區間以及,只無非這個區間是靠右端點的;你可能又想問,不是說區間是靠右端點的嗎,是后綴以及啊,那中間的這些區間怎么界說?實在遞回界說就好了,譬如說:

\(∑6i=1=(a[1]+a[2]+a[3]+a[4]+(a[5]+a[6])=\)

\(∑6i=1=(a[1]+a[2]+a[3]+a[4])+c[6]\)

\(∑i=16=(a[1]+a[2]+a[3]+a[4])+(a[5]+a[6])=\)

\(∑i=16=(a[1]+a[2]+a[3]+a[4])+c[6];\)

你可以把\(c[6]\)往失,就釀成了

\(∑4i=1=(a[1]+a[2]+a[3]+a[4])\)

\(∑i=14=(a[1]+a[2]+a[3]+a[4])\)

這個區間就靠右端點了,

\(∑4i=1=c[4]=c[6-lowbit(6)]\)

\(∑i=14=c[4]=c[6-lowbit(6)]\)。

設計一種數據布局,必要的操作不過便是變動以及查問,
這里只接頭查問地下運彩ptt以及點竄操作詳細是怎么完成的;

查問

這里說的查問是查問任一區間的以及,因為區間以及具備可加減性,以是轉化為求前綴以及;
查問前綴以及便是把大區間分紅幾段長度不等的小區間,然后再乞降。
區間的個數為\(O(logn*logn)\),
以是查問的時間龐大度為\(O(logn*logn)\)。

點竄

點竄某一名置上的元素的時間龐大度為\(O(1)\),
然則要更新\(c\)數組,否則查問的時間龐大度就會變高。
更新的要領就要提一下樹狀數組的性子了以及樹狀數組那張經典的圖片了。

圖片中已經經把\(c\)數組的后綴以及這個寄義已經經抒發得很清晰了。
這個時辰你再把查問操尷尬刁難應到這張圖上,
然后依據二進制來操作,
就可以很直白地輿解下面所說的查問操作了!

樹狀數組的代碼完成

對某個元素進行加法操作:

void update(int x)
{
    while(x<=n)
    {
        c[i]+=x;
        x+=lowbit(x);
    }
}

查問前綴以及:

int sum(int x)
{
    int res=0;
    while (x>0)
    {
        res+=c[x];
        x-=lowbit(x);
    }
    return res;
}

洛谷樹狀數組題:

【模板】樹狀數組 1:p3374

【模板】樹狀數組 2:p3368

中位數:p1168

逆序對:p1908

虔敬的墓客人:p2154

無絕的生命:p2448

傾銷員:p2672

天主造題的七分鐘:p4514

【免責聲明】本站內容轉載自互聯網,其相關談吐僅代表作者小我私家概念盡非權勢巨子,不代表本站態度。如您發明內容存在版權成績,請提交相關鏈接至郵箱:,咱們將實時予以處置。

麻將online