分塊 基礎,(例題)HDU1556

2021-07-16 15:20:34 字數 2313 閱讀 9313

把乙個長度為a序列分成a√

份,對於每乙個塊分別進行處理,對於一些沒有完全覆蓋乙個塊的情況,我們暴力處理就可以了,這是乙個根號級別的演算法(感覺好難解釋啊qaq)

與區間修改,區間查詢有關係的一些問題,但是要維護的值不能合併,這個時候就可以用分塊了(或者確定用分塊不會超時,然後又比較懶233)

problem description

n個氣球排成一排,從左到右依次編號為1,2,3….n.每次給定2個整數a b(a <= b),lele便為騎上他的「小飛鴿」牌電動車從氣球a開始到氣球b依次給每個氣球塗一次顏色。但是n次以後lele已經忘記了第i個氣球已經塗過幾次顏色了,你能幫他算出每個氣球被塗過幾次顏色嗎?

input

每個測試例項第一行為乙個整數n,(n <= 100000).接下來的n行,每行包括2個整數a b(1 <= a <= b <= n)。

當n = 0,輸入結束。

output

每個測試例項輸出一行,包括n個整數,第i個數代表第i個氣球總共被塗色的次數。

sample input

3 1 1

2 2

3 3

3 1 1

1 2

1 3

0sample output

1 1 1

3 2 1

這是一道區間修改&單點查詢的題目,這一題顯然可以用樹狀陣列or線段樹做,但是這一題也可以用分塊來解決(雖然比較慢)

首先是區間修改,可以想象一下,在分塊之後被覆蓋的點會被分成3個部分:

第乙個部分:乙個塊的後面一部分被覆蓋

第二個部分:乙個塊被完全覆蓋

第三個部分:乙個塊的前面一部分被覆蓋

顯然只有第一和第三個部分都只有乙個塊會出現這一種情況,所以我們可以暴力去做,而對於第二個部分,我們可以用另外乙個陣列來儲存這乙個塊整體的add的情況,在最後查詢答案的時候再重新加上就好了。

單點查詢就用當前點所在塊的add值加上這個點本身的值就可以了

第乙個和第三個部分只有乙個塊,而乙個塊的大小是a√

的,而對於第二種情況,對於每乙個塊都是o(

1)的,而一共只有a√

個塊,所以整個演算法的時間複雜度應該是aa

√ 的。

var

a:array[0..100005]of longint;

b:array[0..400]of longint;

i,j,k,l,n,m,x,y,z,p,t,t1,t2,pp,xx,yy:longint;

procedure

work;

begin

readln(n);

if n=0

then halt;

fillchar(a,sizeof(a),0);

fillchar(b,sizeof(b),0);

t:=trunc(sqrt(n));

if t*tthen inc(t);

if t*tthen p:=t else p:=t-1;//t為塊的個數,p為除了最後乙個塊之外其他塊的大小

z:=1;

for i:=1

to n do

begin

readln(x,y);

while (x mod p<>1) and (x<=y) do

begin

a[x]:=a[x]+z;

inc(x);

end;

while (y mod p<>0) and (y>=x) do

begin

a[y]:=a[y]+z;

dec(y);

end; //這一部分是處理上述的第一和第三種情況的~

x:=x div p+1;

y:=y div p;

for j:=x to y do inc(b[j],z);//第二種情況

end;

for i:=1

to n do

begin

y:=i;

x:=y;

if y mod p=0

then dec(y);

y:=y div p+1;

if ithen

write(a[x]+b[y],' ') else writeln(a[x]+b[y]);//把兩個部分加起來後輸出~

end;

end;

begin

// assign(input,'t1'); reset(input);

while

true

do work;

// close(input);

end.

hdu 1556 初級線段樹

include include include define max 100005 define mid l r 1 define lson l,m,rt 1 define rson m 1,r,rt 1 1 using namespace std int n struct tree tree tr...

HDU 1556樹狀陣列求解

f color the ball time limit 3000msmemory limit 32768kb64bit io format i64d i64u submit status practice hdu 1556 description n個氣球排成一排,從左到右依次編號為1,2,3.n....

HDU 1556 (差分陣列)

題意 n個氣球 1 到 n 編號 然後接下來n行 每行給2個整數 a b,從a到b依次給每個氣球塗一次顏色,n次後操作後忘記了第 i 個氣球塗過幾次顏色了 問算出每個氣球被塗過幾次顏色 思路 資料範圍 n 1e5 1 a,b n 時間 3e9 區間操作和單點查詢 1 線段樹 區間操作 都是log 2...