題意:輸入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 ...