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

2021-07-02 11:35:12 字數 1326 閱讀 7504

題意:輸入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演算法就沒什麼用了,這題一開始看的感覺是單點更新,但是看下資料量單點更新根本不可行。那我們可以想一下給的條件,(i-a)%k==0,可以化成i%k==a%k。對於a%k 就很好求了,所以我們可以列舉一下所有的mod 情況,因為k最大只是10,所以mod 的所有情況有55種。我們把這些mod 的情況都存下來,在更新的時候只更新(a%k)的,把(a%k)的都加起來,查詢的時候在只把(i%k)的值加上,相當於用乙個陣列modleft[i][j]存一下某個數對於mod i 餘數為j,這樣就可以利用lazy的思想,只在查詢的時候把值全部加起來,起到延遲標記的

#include #include const int maxn=50005;

int k,modleft[11][11];//表示某個數mod i 餘 j

struct node

tree[maxn<<2];

void pushdown(int id) }}

void build(int l,int r,int id)

int mid=l+r>>1;

build(l,mid,id<<1);

build(mid+1,r,id<<1|1);

}void updata(int l,int r,int l,int r,int id,int lmodk,int k,int c)

pushdown(id);

int mid=l+r>>1;

if(l<=mid)updata(l,r,l,mid,id<<1,lmodk,k,c);

if(r>mid)updata(l,r,mid+1,r,id<<1|1,lmodk,k,c);

}int query(int l,int r,int id,int x)

tree[id].sum=s;

return s;

} pushdown(id);

int mid=l+r>>1;

if(x<=mid)return query(l,mid,id<<1,x);

return query(mid+1,r,id<<1|1,x);

}int main()

{ int n,a,b,m,k,c,i,j,q;

int cnt=0;

for(i=1;i<=10;i++)//初始化modleft,共55中情況

for(j=0;j

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...

hdu4267(樹狀陣列,有規則區間修改)

hdu4267 題目大意 一段序列,修改某個區間 下標號成等差序列 的元素的值,查詢某個點的值 對每個公差 以及 某段開始下標對每個公差的取餘 確定某個點被修改的方式,或者這個修改的起始位置?建立k k個樹狀陣列 include include include include include inc...

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

題意 給你n個數,q組操作,操作有兩種,查詢和改變,查詢就是查詢當前的這個數上有多少,更改是給你a b k c,每次從a到b,每隔k的數更改一次,之間的數不更改,就相當於跳著更新.思路 別人的 i a k 0 等價於 i k a k 一共有10中情況 還有列舉所有情況中的小情況 1 1 2 3 4 ...