HDU1698 just a Hook - 帶有lazy標記的線段樹
阿新 • • 發佈:2017-08-30
hdu 1698 tle 抽象 過多 using urn 多次 區間查詢 端點
2017-08-30 16:44:33
writer:pprp
上午剛剛復習了一下不帶有lazy標記的線段樹,
下午開始學帶有lazy標記的線段樹
這個是我看大佬代碼敲的,但是出了很多問題,
這提醒我:
1、要註意邊界條件,一個邊界條件的取等或者不取等,小於或者大於出錯的話就直接運行不了了
2、註意輸入輸出,經過多次測試,果然還是用scanf比較保險,試了試用fast_io的cin結果還是TLE
所以以後不要用cin了,cin害人啊,兩個混用就更加麻煩了
這個題就是區間修改,區間查詢的一道題,但是大佬沒有用指針構造一個結構體
僅僅抽象了一個sum和一個add(lazy標記)
感覺簡單了不少
代碼如下:
/* @theme:segmentation/interval tree @writer:pprp @begin:15:26 @end:16:13 @declare: 使用lazy標記的線段樹,HDU 1698 @date:2017/8/30 */ #include <iostream> #include <cstdio> #define Mid ((l+r)>>1) #define lson rt<<1,l,Mid #define rson rt<<1|1,Mid+1,r const int maxn = 100010; int sum[maxn<<2],add[maxn<<2]; using namespace std; void build(int rt,int l, int r) { add[rt] = 0; //這裏是每個節點都是1的情況 if(l == r) sum[rt] = 1; else { build(rson); build(lson); sum[rt] = sum[rt<<1]+sum[rt<<1|1]; } } void pushDown(int rt, int len) {//將父節點的add值傳遞下來 add[rt<<1] = add[rt<<1|1] = add[rt]; //將左右的值進行區間更新 sum[rt<<1] = (len - (len>>1))*add[rt]; sum[rt<<1|1] = (len>>1)*add[rt]; //將父節點的add值清空 add[rt] =0; } //L,R代表的要更新區間的左右端點,z是區間增加的值 void update(int rt, int l,int r, int L, int R, int z) { //如果在L,R的內部 if(L <= l && r <= R) //error { add[rt] = z; sum[rt] = (r - l + 1) * z; } else //沒有找到該節點 { if(add[rt])//當前節點不為空,要傳下去 pushDown(rt,r-l+1); if(L <= Mid) update(lson,L,R,z); if(R >= Mid) //error update(rson,L,R,z); sum[rt] = sum[rt<<1]+sum[rt<<1|1]; } } int main() { // RE; int t,n,q,x,y,z; int cnt=1; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&q); build(1,1,n); while(q--){ scanf("%d%d%d",&x,&y,&z); update(1,1,n,x,y,z); } printf("Case %d: The total value of the hook is %d.\n", cnt++,sum[1]); } return 0; }
HDU1698 just a Hook - 帶有lazy標記的線段樹