hdu4267線段樹段更新,點查詢,55棵線段樹

2022-09-05 01:09:11 字數 2148 閱讀 9718

題意:

給你n個數,q組操作,操作有兩種,查詢和改變,查詢就是查詢當前的這個數上有多少,更改是給你a b k c,每次從a到b,每隔k的數更改一次,之間的數不更改,就相當於跳著更新.

思路:(別人的)

(i - a) % k == 0 等價於 i % k == a % k 一共有10中情況

還有列舉所有情況中的小情況

(1)1 2 3 4 5 6 7 8 9.....

(2)1 3 5 7 9 11 13 ......

2 4 6 8 10 12 14......

(3)1 4 7 10 13...

2 5 8 11 14...

3 6 9 12 15...

一共1 + 2 +....+ 10 = 55種

其實每乙個數字必然在這55種情況中的10種,對於每次更新就是更新這個陣列在這55種情況中的1種,而查詢就是查詢這個數字的10種情況的和,陣列num[t][key],t是線段樹上的點,key是這55中情況中的一種,對於每乙個點a ,key = a % k + k * (k - 1) / 2 ,這樣相當於我們直接建了55棵樹,對於每個區間更新的時候,我們直接可以用線段樹的短更新,

比如1--5,k = 2,我們直接找到 key = 1 % 2 + 2 * (2 - 1) / 2 = 2,則可以確定的是在第二課樹上,我們把所有1--5的在第二棵樹上的都更新看下上面發現第2課樹上沒有2,4我們也更新了num[2][2] ,num[4][2],雖然更新了,但在查詢的時候永遠不可能查詢的到的,同時它把操作變成了連續的,這樣就可以用線段樹的 段更新點查詢模板ac了...

#include

#include#define lson l,mid,t<<1

#define rson mid+1,r,t<<1|1

intnum[150000][55];

intaa[50000];

voidupdate(

intl,

intr,

intt,

inta,

intb,

intc,

intkey)

intmid= (l+r) >>1;

if(a<=mid)update(lson,a,b,c,key);

if(b>mid)update(rson,a,b,c,key);

return;}

intquery(

intl,

intr,

intt,

inta)

intmain

()else}}

return0;

}

hdu 4267 十顆線段樹

線段樹 i a k 0 即i k a k 節點維護乙個二維陣列add,add a b c,表示該區間下標i a b的加c 那麼,update l,r,k,l k,v 這樣就可以分到子區間了 但是,這樣會爆記憶體,因為a b include include includeusing namespace...

HDU 4267 線段樹區間內部某個值更新

題意 輸入n 下面有n個數,q個操作,對於每次操作 有兩種情況。情況1.輸入1 a b k c,表示更新操作,將a b區間內的符合a i b and i a k 0.的數都 c。情況2 輸入2 a 表示查詢操作,輸出a 上的值。思路 對於這種不是對整個區間都進行更新的操作,似乎lazy演算法就沒什麼...

hdu1689 線段樹成段更新

兩種操作 1 set區間 a,b 上數字為v 2 查詢 1 n 上的sum 如下 include include include include include include include include include include include include define n 1000...