分治算法


分治算法

 

一、二分

二分本質是求邊界

一定面對有序的,可以是大小,也可以是性質

 

你看這個二分查找

 

 

寫好二分

首先你要有好模板

 

 

 

 典型例題

1.借教室

 

 

打標記(差分維護前綴和)

O(1)打標記,O(n)求前綴和

O(m)是訂單數

O(m+n)求出每天需要多少教室

 

 

 

 2.

解析

在數字1~num中,

u表示能被x整除的數的個數 

v表示能被y整除的數的個數

w 表示能被x*y整除的數的個數

因為在[1, num]里面,只有x,2x,3x,4x...

這么幾個數能被 x 整除,而且對於 kx,需要保證 kx <= num

所以顯然 k = floor(num / x)

 

二、三分

 

 

復雜度:log3/2N

 

如何比較兩個實數的大小呢??

如果我們有兩個數字 a,b
經過一系列玄學操作
a,b在計算的時候精度可能會丟失
此時做差判斷他們到底誰大

double eps=1e-8;
fabs(a-b)<eps return 0;  //表示a=b
return a-b<0?-1:1; 

 

 

那如果函數不是單峰怎么辦?

 

 

 三、分塊

1.給出一個長度為n的數列,以及m個操作,支持區間加法,單點查詢

(PS,為什么不用線段樹??)

我們分塊!!!

吧長為n的數組分成√n個塊

 

給出詢問區間 [ L , R ]

情況1:L,R在同一塊里,暴力跑

情況2:L,R在相鄰塊里,暴力跑

情況3:L,R在不相鄰塊里,L~R之間每個塊打標記

單點查詢:自己加標記

 

 2.給出一個長為n的數列以及m個操作,支持區間加法,並詢問區間內小於等於某個數x的元素個數

 

長度為n的數列a,我們把它分塊到b數組,√n一個塊,然后每個塊內部進行排序

 

(1) 給出詢問區間 [ L , R ]

還是考慮三種情況

情況1:L,R在同一塊里,暴力掃描    O(√n)

情況2:L,R在相鄰塊里,暴力掃描    O(2√n)

情況3:L,R在不相鄰塊里                  O(√n log n)

 

 

 (2) 區間加

      L,R在一個塊里就直接加啊,然后跑一遍快排  O(√n log n)

   但是它的復雜度可以再低一點,達到

  用均值不等式調整分塊大小,查詢復雜度和修改復雜度取均值不等式

 

 

3.給出一個長為n的數列以及m個操作,支持區間開放,區間求和

一個longlong 最多開方6次變1

掃描區間,若是01的一段區間,就標記,以后開方不用動了,因為不會改變了呀

 

 

 

 

 

假設你有一堆彈珠

紅黃藍綠紅綠藍紫粉黃粉藍

color[i]:下標為i的球的顏色

pre[i]:前一個顏色為color[i]的球的下標編號

引理:

如果 pre[i]<x<i,那么在區間[x,i]之間有一個顏色為color[i]的球

so,

查詢區間[l,r]里有多少不同顏色,等價於

查詢區間[l,r]之間pre[i]<l的i的個數

也就是求[l,r]里有多少個pre[i]<l

這個可以用上面講的2做

 

O(n)暴力修改能過

 


 

 題外話

 推薦oj 

1.CF(cross fire(不是)) CodeForce

2.CodeChef(對高中生還算友好)

3.TopCoder

4.Div2

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM