欧美亚洲综合图区在线|天天射天天干国产成卜|99久久免费国产精精品|国产的欧美一区二区三区|日韩中文字幕无码不卡专区|亚麻成人aV极品一区二区|国产成人AV区一区二区三|成人免费一区二区三区视频网站

當(dāng)前位置:首頁 > 軟件開放 > 正文內(nèi)容

jquery彈框代碼(jquery 彈框)

軟件開放1個月前 (11-19)169

本篇內(nèi)容包括了分塊算法的思想的介紹、分塊算法復(fù)雜度的分析以及相關(guān)例題。

*本文內(nèi)容由羅勇軍老師提供。

01

分塊概念

回顧“區(qū)間”問題,前面給出了暴力法、樹狀數(shù)組、線段樹等算法。給定一個保存n個數(shù)據(jù)的數(shù)列,做m次“區(qū)間修改”和“區(qū)間查詢”,每次操作只涉及到部分區(qū)間。暴力法只是簡單地從整體上做修改和查詢,復(fù)雜度O(mn),很低效。樹狀數(shù)組和線段樹都用到了二分的思想,以O(shè)(logn)的復(fù)雜度組織數(shù)據(jù)結(jié)構(gòu),每次只處理涉及到的區(qū)間,從而實現(xiàn)了O(mlogn)的高效的復(fù)雜度。

雖然暴力法只能解決小規(guī)模的問題,但是它的代碼非常簡單。

有一種代碼比樹狀數(shù)組、線段樹簡單,效率比暴力法高的算法,稱為“ 分塊”,它能以O(shè)(m√n)的復(fù)雜度解決“區(qū)間修改+區(qū)間查詢”問題。簡單地說,分塊是用線段樹的“分區(qū)”思想改良的暴力法;它把數(shù)列分成很多“塊”,對涉及到的塊做整體性的維護操作(類似于線段樹的lazy-tag),而不是像普通暴力法那樣處理整個數(shù)列,從而提高了效率。

用一個長度為n的數(shù)組來存儲n個數(shù)據(jù),把它分為t塊,每塊長度為n/t。下圖(1)是一個有10個元素的數(shù)組,共分成4塊,前3塊每塊3個元素,最后一塊1個元素。

▍ 圖1 (1)分塊 ????? (2)與線段樹的結(jié)構(gòu)對比

對比塊狀數(shù)組與線段樹,線段樹是一棵高度為logn的樹,塊狀數(shù)組可以看成一棵高度為3的樹,見圖(2)。從圖(2)可知,在線段樹上做一次操作是O(logn)的,因為它有l(wèi)ogn層;分塊是O(n/t)的,因為它把數(shù)據(jù)分成了t塊,處理一塊的時間是n/t的。下面介紹分塊算法,并詳細說明復(fù)雜度。

02

分塊算法

塊操作的基本要素有:

(1)塊的大小。用block表示。

(2)塊的數(shù)量。用t表示。

(3)塊的左右邊界。定義數(shù)組st[]、ed[],用st[i]、ed[i]表示塊i的第一個和最后一個元素的位置。st[1] = 1,ed[1] = block;st[2] = block+1,ed[2] = 2×block;…;st[i] = (i-1)*block+1,ed[i] = i*block;…

(4)每個元素所屬的塊。定義pos[],pos[i]表示第i個元素所在的塊,pos[i]=(i-1)/block + 1。

具體內(nèi)容見下面的代碼。其中每塊的大小block的值等于√n取整,后面的“復(fù)雜度分析”會說明原因。如果√n的結(jié)果不是整數(shù),那么最后要加上一小塊,代碼中重要的內(nèi)容是處理這個問題。

展開全文

intblock = sqrt(n); //塊的大小:每塊有block個元素。

intt = n/block; //塊的數(shù)量:共分為t塊

if(n % block) t++; //sqrt(n)的結(jié)果不是整數(shù),最后加一小塊

for( inti= 1; i=t; i++){ //遍歷塊

st[i] = (i -1)*block+ 1;

ed[i] = i*block;

}

ed[t] = n; //sqrt(n)的結(jié)果不是整數(shù),最后一塊較小

for( inti= 1; i=n; i++) //遍歷所有元素的位置

pos[i]=(i -1)/block + 1;

用分塊解決區(qū)間問題很方便,下面以“區(qū)間修改+區(qū)間查詢”(洛谷P3372)為例。

首先定義區(qū)間有關(guān)的輔助數(shù)組:

(1)定義數(shù)組a[]存儲數(shù)據(jù),共n個元素,讀取初值,存儲在a[1]、a[2]、…、a[n]中。

(2)定義sum[],sum[i]為第i塊的區(qū)間和,并預(yù)處理出初值。

for( inti= 1; i=t; i++) //遍歷所有的塊

for( intj=st[i]; j=ed[i];j++) //遍歷塊i內(nèi)的所有元素

sum[i] += a[j];

(3)定義add[],add[i]為第i塊的增量標記,初始值為0。

然后對數(shù)列a[]做“區(qū)間修改+區(qū)間查詢”操作:

1. 區(qū)間修改:將區(qū)間[L, R]內(nèi)每個數(shù)加上d。

情況1,[L, R]在某個i塊之內(nèi),即[L, R]是一個“碎片”。把a[L]、a[L+1]、…、a[R]逐個加上d,更新sum[i] = sum[i] + d*(R - L + 1)。計算次數(shù)約為n/t。

情況2,[L, R]跨越了多個塊。在被[L, R]完全包含的那些整塊內(nèi)(設(shè)有k個塊),更新add[i] = add[i] + d。對于不能完全包含的那些碎片(它們在k個整塊的兩頭),按情況1處理。情況2的計算次數(shù)約為n/t + k,1 ≤ k ≤ t。

總結(jié)兩種情況,處理碎塊時,只更新sum[i],不更新add[i];處理整塊時,只更新add[i],不更新sum[i]。

voidchange( intL, intR, intd ) {

intp = pos[L], q = pos[R];

if(p==q){ //情況1,計算次數(shù)是n/t

for( inti=L;i=R;i++) a[i]+=d;

sum[p]+=d*(R-L+ 1);

}

else{ //情況2

for( inti=p+ 1;i=q -1;i++) add[i]+=d; //整塊,有m=(q-1)-(p+1)+1個。計算m次

for( inti=L;i=ed[p];i++) a[i]+=d; //整塊前面的碎片。計算n/t次

sum[p]+=d*(ed[p]-L+ 1);

for( inti=st[q];i=R;i++) a[i]+=d; //整塊后面的碎片。計算n/t次

sum[q]+=d*(R-st[q]+ 1);

}

}

2. 區(qū)間查詢:輸出區(qū)間[L, R]內(nèi)每個數(shù)的和。

情況1,[L, R]在某個i塊之內(nèi)。暴力加每個數(shù),最后加上add[i],答案是ans = a[L] + a[L+1] + … + a[R] + (R - L + 1)*add[i]。計算次數(shù)約為n/t。

情況2,[L, R]跨越了多個塊。在被[L, R]完全包含的那些塊內(nèi)(設(shè)有k個塊),ans += sum[i] + add[i]*len[i],其中l(wèi)en[i]是第i段的長度,等于n/t。對于不能完全包含的那些碎片,按情況1處理,然后與ans累加。計算次數(shù)約為n/t + k,1 ≤ k ≤ t。

longlongask( intL, intR ) {

intp=pos[L],q=pos[R];

longlongans= 0;

if(p==q){ //情況1

for( inti=L;i=R;i++) ans += a[i];

ans+= add[p]*(R-L+ 1);

}

else{ //情況2

for( inti=p+ 1;i=q -1;i++) ans+=sum[i]+ add[i]*(ed[i]-st[i]+ 1); //整塊

for( inti=L;i=ed[p];i++) ans += a[i]; //整塊前面的碎片

ans += add[p]*(ed[p]-L+ 1);

jquery彈框代碼(jquery 彈框)

for( inti=st[q];i=R;i++) ans += a[i]; //整塊后面的碎片

ans += add[q]*(R-st[q]+ 1);

}

returnans;

}

分塊算法的實現(xiàn)簡單粗暴,沒有復(fù)雜數(shù)據(jù)結(jié)構(gòu)和復(fù)雜邏輯,很容易編碼。

分塊算法的思想,可以概況為 “整塊打包維護,碎片逐個枚舉”。

03

復(fù)雜度分析

把數(shù)列分為t塊,t取何值時有最佳效果?

觀察一次操作的計算次數(shù)n/t和n/t+k,其中1≤k≤t;當(dāng)t=√n 時,有較好的時間復(fù)雜度O(√n)。m次操作的復(fù)雜度是O(m√n),適合求解m=n=10 5 規(guī)模的問題,或 O(m√n)≈10 7 的問題。對復(fù)雜度的直觀理解,請看圖。

空間復(fù)雜度:需要分配長度為 的數(shù)組st[]、ed[]、sum[]、add[]和長度為n的pos[]、a[],約3*MAXN,比線段樹的9*MAXN好得多。不過,分塊只能解決m = n = 10 5 規(guī)模的問題,而線段樹是10 6 規(guī)模的,應(yīng)用場景不同,直接對比空間無意義。

04

例題

有些題目用普通的線段樹、樹狀數(shù)組求解很難編碼,而用分塊比較容易。

例題1:區(qū)間第k大問題

教主的魔法洛谷P2801

題目描述:有N個數(shù),有兩種操作,區(qū)間修改(加)、區(qū)間詢問。

輸入:第1行有兩個整數(shù)n、m。第2行有n個正整數(shù)。第3行到第m + 2行,每行是一個操作,有兩種操作:

(1)第一個字母是“M”,后面三個數(shù)字L、R、W,表示對閉區(qū)間[L, R]內(nèi)每個數(shù)加上W。

(2)第一個字幕是A,后面三個數(shù)字L、R、C,詢問閉區(qū)間[L, R]內(nèi)有多少數(shù)字大于等于C。

輸出:對每個“A”詢問輸出一行,包含一個整數(shù),表示大于等于C的數(shù)有多少個。

數(shù)據(jù)范圍:n ≤ 1,000,000,m ≤3000,1 ≤ W≤1000,1 ≤ C≤1,000,000,000

題解:

如果用復(fù)雜度O(mn)的算法,不能通過測試。

詢問區(qū)間[L, R]有多少數(shù)字大于等于C,等同于問C是區(qū)間第幾大,即“區(qū)間第k大”問題,標準解法是主席樹,m次操作的復(fù)雜度是O(mlogn)。

本題的n較小,用“分塊 + 二分”算法,復(fù)雜度滿足要求,而且代碼很容易寫。容易想到以下分塊操作方法:

(1)首先讀取數(shù)列a[],把它分為√n塊。

(2)區(qū)間修改。每個塊維護一個add標記,用于記錄塊內(nèi)的增量W;更新時,區(qū)間內(nèi)的整塊更新add,不完整的碎片,暴力更新其中的每個數(shù)。

(3)區(qū)間查詢。大于等于C的數(shù)有多少?如果直接暴力搜每個塊,復(fù)雜度為O(n),不能滿足要求。如果塊中的數(shù)是有序的,那么用二分來找大于C的數(shù),復(fù)雜度為O(logn)。但是塊內(nèi)的數(shù)是無序的,需要先排序再用二分(可以直接用lower_bound函數(shù)),復(fù)雜度O(nlogn + logn),還不如直接暴力搜。如果能“一次排序,多次使用”,就高效了。

下面是改進后的算法。

(1)在區(qū)間操作前,對每個塊的初始值排序,復(fù)雜度O(nlogn)。不過,排序會改變原來元素的位置,所以定義一個輔助數(shù)組b[],它的初值是數(shù)列a[]的復(fù)制,排序操作在b[]上進行。也就是說,b[]的每個塊內(nèi)部都是有序的,對b[]的某個塊統(tǒng)計前k個數(shù),就是對a[]的對應(yīng)塊統(tǒng)計前k個數(shù)。

(2)區(qū)間修改。如果是整塊,維護add標記,不用在b[]上對整塊再排序,因為它仍然保持有序;如果是碎片,暴力修改a[]上對應(yīng)位置的數(shù),然后把碎片所在的整塊復(fù)制到b[]上,對這個塊重新排序。復(fù)雜度 = 整塊維護 + 碎片排序 = O(√n + √n l o g (√ n ))。

(3)區(qū)間查詢。對整塊,因為已經(jīng)是有序的,直接在b[]的對應(yīng)整塊上二分查詢;對碎塊,暴力搜a[]上的碎塊。復(fù)雜度 = 整塊查詢 + 碎片查詢 = O(√nlog(√n)+√n)。

做m次區(qū)間操作,以上三者相加,總復(fù)雜度是O(nlogn)+O(m(√n+√nlog(√n))≈O(m√nlog(√n))。勉強通過測試。

例題2:hdu 5057

Argestes and Sequencehdu 5057

Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

題目描述:給定一個序列,有n個非負整數(shù)a[1], a[2],…, a[n]。做“單點修改 + 區(qū)間查詢”操作。

輸入:第一行是整數(shù)T,表示測試用例數(shù)量。對每個測試,第一行包含兩個數(shù)字n、m。第二行是n個非負整數(shù),用空格分割,后面有m行,每行表示一個操作,有兩種操作:

S X Y: 修改操作,把a[x]的值置為y,即a[x] = y;

Q L R D P: 查詢操作,詢問區(qū)間[L, R]內(nèi)有多少個數(shù)的第D位是P。

輸出:對每個Q詢問,輸出一行答案。

數(shù)據(jù)范圍:1≤T≤50,1≤n, m≤100000,0≤a[i]≤2 31 -1,1≤L≤R≤n,1≤D≤10,0≤P≤9

題解:

首先試試分塊,看復(fù)雜度是否符合要求。

用分塊編碼非常容易。把數(shù)組分為√n塊,然后定義block[i][D][P],表示第i塊第D位是P 的總個數(shù)。

(1)初始化。讀取數(shù)組a[]的初值,根據(jù)a[]計算出block[][][]的初值。復(fù)雜度O(n)。

(2)修改操作。單點修改a[x],根據(jù)a[x]更新block[][][]。復(fù)雜度O(1)。

(3)查詢操作。在碎片上,暴力計算[L, R]內(nèi)的每個a[]。在整塊上,累加所有整塊的block[][][]即可。復(fù)雜度 = 整塊的計算 + 碎片的計算 = O(√n) + O(√n) = O(√n)。

總復(fù)雜度 = 初始化 + m個操作 = O(n) + O(m√n),勉強通過測試。

此題也可以用樹狀數(shù)組,并且這是一道練習(xí)樹狀數(shù)組的好題。樹狀數(shù)組的基礎(chǔ)功能是“單點修改 + 區(qū)間查詢”,符合本題的要求。

一個數(shù)據(jù)最多有D = 10位,每位有P = 0~9這10個數(shù),所以詢問共有D*P = 10*10 = 100種情況。

如果所有的操作只涉及一種情況,用樹狀數(shù)組很容易編程。例如所有的a[i]都只有1位,這1位要么是0,要么是1,然后詢問區(qū)間[L, R]內(nèi)有多少個1。這是最基本的樹狀數(shù)組。

(1)先讀取并保存所有的修改和查詢操作。

(3)按順序輸出查詢的結(jié)果。

計算復(fù)雜度是多少?上面的步驟,等于做了10次O(mlogn)的樹狀數(shù)組,注意不是做了100次,請思考原因。樹狀數(shù)組的效率比分塊高很多,不過編碼的難度要高很多倍。

例題3:洛谷 P3203

題目描述:一條直線上擺著n個彈簧,每個彈簧有彈力系數(shù)k i ,當(dāng)綿羊到第i個彈簧時,它會被彈到第i+k i 個位置,若不存在第i+k i 個彈簧,則綿羊被彈飛。

綿羊想知道當(dāng)它從第i個彈簧起步時,被彈幾次后會被彈飛。為了使游戲有趣,允許修改某個彈簧的彈力。彈力系數(shù)始終為正。

輸入:第一行包含一個整數(shù)n,表示地上有n個裝置,編號0~n-1。接下來有n個正整數(shù),依次為n個彈簧的初始彈力系數(shù)。第三行有一個正整數(shù)m,表示操作次數(shù)。

接下來m行每行至少有兩個數(shù)i,j。

若i=1,你要輸出從j出發(fā)被彈幾次后彈飛。

若i=2,則再輸入一個正整數(shù)k,表示第j個彈簧的彈力系數(shù)被改成k。

輸出:對每個i=1的操作,輸出一行一個整數(shù)表示答案。

數(shù)據(jù)范圍:1≤n≤2×10 5 ,1≤m≤10 5 。

題解:

本題是“單點修改+單點查詢”,如果用暴力法,每次查詢是O(n)的,m次操作,總復(fù)雜度O(mn),超時。本題的標準解法是動態(tài)樹LCT,復(fù)雜度O(mlogn)。下面用分塊求解,編碼很簡單,復(fù)雜度O(m√n),勉強通過測試。

把整個序列分成√n塊,對于每個點i,維護兩個值:step[i]表示綿羊從第i個點彈出它所在的塊所需要的次數(shù)、to[i]表示從第i個點所在的塊彈出后落到其他塊的點。先預(yù)處理初始值,復(fù)雜度O(n)。

單點查詢。從起點出發(fā),根據(jù)to[]找到下一個點(這個點在其他塊里),累加這個過程中所有的step[]即得到總次數(shù),大于n的時候跳出。最多經(jīng)過√n個塊,每塊計算一次,復(fù)雜度O(√n)。

單點修改。step[i]和to[i]只與i所在的塊有關(guān),與其他塊無關(guān),所以單點修改只需要維護一個塊,復(fù)雜度O(√n)。

05

實現(xiàn)代碼

掃描二維碼推送至手機訪問。

版權(quán)聲明:本文由飛速云SEO網(wǎng)絡(luò)優(yōu)化推廣發(fā)布,如需轉(zhuǎn)載請注明出處。

本文鏈接:http://landcheck.net/post/124098.html

“jquery彈框代碼(jquery 彈框)” 的相關(guān)文章

網(wǎng)站建設(shè)方案(網(wǎng)站建設(shè)方案書范文)

網(wǎng)站建設(shè)方案(網(wǎng)站建設(shè)方案書范文)

本篇文章給大家談?wù)劸W(wǎng)站建設(shè)方案,以及網(wǎng)站建設(shè)方案書范文對應(yīng)的知識點,希望對各位有所幫助,不要忘了收藏本站喔。 本文目錄一覽: 1、網(wǎng)站建設(shè)的方案包括有哪些內(nèi)容? 2、網(wǎng)站建設(shè)方案都包括什么? 3、網(wǎng)站建設(shè)規(guī)劃書 4、網(wǎng)站建設(shè)方案需要考慮到哪些方面? 5、企業(yè)網(wǎng)站建設(shè)規(guī)劃方案怎么寫?...

iQOO手機怎么查看安卓id(iqoo手機里怎么查看手機配置)

iQOO手機怎么查看安卓id(iqoo手機里怎么查看手機配置)

本篇文章給大家談?wù)刬QOO手機怎么查看安卓id,以及iqoo手機里怎么查看手機配置對應(yīng)的知識點,希望對各位有所幫助,不要忘了收藏本站喔。 本文目錄一覽: 1、iQOO怎么打開手機識別碼或者IMEI權(quán)限 2、設(shè)備ID怎么查看? 3、怎么看iqoo手機版本國行其他版本 4、iqooneo3序...

用Python設(shè)計小游戲(python設(shè)計小游戲誰先走到17誰就贏)

用Python設(shè)計小游戲(python設(shè)計小游戲誰先走到17誰就贏)

本篇文章給大家談?wù)動肞ython設(shè)計小游戲,以及python設(shè)計小游戲誰先走到17誰就贏對應(yīng)的知識點,希望對各位有所幫助,不要忘了收藏本站喔。 本文目錄一覽: 1、Python實現(xiàn)消消樂小游戲 2、用Python寫一個簡單的小游戲 3、python簡單小游戲代碼 怎么用Python制作簡單小...

裝修工程報價表(工程裝修報價明細表)

裝修工程報價表(工程裝修報價明細表)

今天給各位分享裝修工程報價表的知識,其中也會對工程裝修報價明細表進行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧!本文目錄一覽: 1、裝修工程報價單范本哪位有?都包括了哪些項目呢? 2、裝修公司工程明細報價表出錢嗎 3、裝修報價中常見的幾個坑 你遇到幾個 4、新手必看...

王者榮耀的源碼(王者榮耀源碼曝光)

王者榮耀的源碼(王者榮耀源碼曝光)

今天給各位分享王者榮耀的源碼的知識,其中也會對王者榮耀源碼曝光進行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧!本文目錄一覽: 1、同一個王者榮耀帳號,安卓和蘋果是否共用游戲時間 2、王者榮耀怎么自己做皮膚 3、為什么王者榮耀每次下載了還要更新,而不是直接可以登錄賬號?...

中央13臺在線直播觀看高清(中央13臺在線直播觀看高清央視新聞天氣預(yù)報)

中央13臺在線直播觀看高清(中央13臺在線直播觀看高清央視新聞天氣預(yù)報)

今天給各位分享中央13臺在線直播觀看高清的知識,其中也會對中央13臺在線直播觀看高清央視新聞天氣預(yù)報進行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧!本文目錄一覽: 1、CCTV13怎么在手機上看到? 2、中央電視臺13套直播在線觀看高清漠河到長沙多遠 3、中央電視臺13...

沙雅县| 博湖县| 元谋县| 石屏县| 高州市| 萨嘎县| 五台县| 安远县| 北辰区| 航空| 宜章县| 利川市| 股票| 湘西| 洛宁县| 且末县| 呼和浩特市| 芮城县| 蛟河市| 老河口市| 西乌珠穆沁旗| 巴彦淖尔市| 澳门| 静宁县| 阿拉尔市| 卢氏县| 离岛区| 安顺市| 海丰县| 安丘市| 齐齐哈尔市| 东港市| 周口市| 平安县| 扶余县| 和龙市| 永泰县| 西乌珠穆沁旗| 平定县| 金山区| 汉源县|