1. 程式人生 > >HDU1698 just a Hook - 帶有lazy標記的線段樹

HDU1698 just a Hook - 帶有lazy標記的線段樹

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標記的線段樹