題意:
給你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...