線段樹懶標記好題 HDU4578

2022-08-20 22:54:11 字數 2653 閱讀 7490

(1)"1 x y c",代表 把區間 [x,y] 上的值全部加c

(2)"2 x y c",代表 把區間 [x,y] 上的值全部乘以c

(3)"3 x y c" 代表 把區間 [x,y]上的值全部賦值為c

(4)"4 x y p" 代表 求區間 [x,y] 上值的p次方和1<=p<=3

維護sum1, sum2, sum3分別為一次方、二次方、三次方的和

因為p只有1到3,(x+c)^2=(x^2)+(2*x*c+c^2),即我們可以從一次方和的結果推出二次方的和的結果。同理,我們也可以根據一次方的和的結果,二次方和的結果推出三次方和的結果。這樣,我們可以用幾個懶標記去記錄這幾個操作。但是這題明白上面這點還是不夠的,因為,這幾種更新操作之間會相互影響,比如對乙個區間進行操作3之後,那麼操作1和2就失效了。因此在pushdown傳遞懶標記的時候,傳遞的順序也是重要的。

1 #include 2 #include 

3 #include 4 #include 5

#define pb push_back

6#define fi first

7#define se second

8#define lson(r) (r<<1)

9#define rson(r) ((r<<1)|1)

1011

using

namespace

std;

1213 typedef long

long

ll;14

15const

int maxn = 1e5+7;16

const

int maxv = 507;17

const

int maxe = 507;18

const ll mod = 10007

;19 ll sum1[maxn << 2

];20 ll sum2[maxn << 2

];21 ll sum3[maxn << 2

];22 ll addmark[maxn << 2

];23 ll setmark[maxn << 2

];24 ll mulmark[maxn << 2

];25

26void pushdown(int root, int l, int

r)27

49if (mulmark[root] != 1)50

64if

(addmark[root])

6577}78

void update(int root, int l, int r, int ul, int ur, int

mathod, ll val)

7994

else

if (mathod == 2)95

102else

if (mathod == 3

)103

112return

;113

}114

pushdown(root, l, r);

115int mid = (l+r) >> 1

;116

if (ul <=mid) update(lson(root), l, mid, ul, ur, mathod, val);

117if (ur > mid) update(rson(root), mid+1

, r, ul, ur, mathod, val);

118 sum1[root] = (sum1[lson(root)] + sum1[rson(root)]) %mod;

119 sum2[root] = (sum2[lson(root)] + sum2[rson(root)]) %mod;

120 sum3[root] = (sum3[lson(root)] + sum3[rson(root)]) %mod;

121//

cout << l << " " << r << " " << sum1[root] << endl;

122}

123124

int cnt = 0

;125 ll query(int root, int l, int r, int ql, int qr, int

p)126

135pushdown(root, l, r);

136int mid = (l+r) >> 1

;137 ll res = 0

;138

if (ql <= mid) res = (res + query(lson(root), l, mid, ql, qr, p)) %mod;

139if (qr >= mid+1) res = (res + query(rson(root), mid+1, r, ql, qr, p)) %mod;

140return

res;

141}

142int

n, m;

143int

main()

144164

else

if (op == 2

) 165

168else

if (op == 3

) 169

172else

173177

}178

}179

return0;

180 }

線段樹懶標記

線段樹在n較小 操作較多的情況下效率很高。雖然如此,如果直接暴力進行修改的話還是會tle得很慘。於是乙個叫做懶標記的東西應運而生。懶標記 why優秀 在修改乙個節點時,若此點已經被懶標記所標記,我們就將此點懶標記取消,標記左右子節點傳遞下去,當被更新或者被查詢時再更新節點,節約了根本不會被用到的花費...

poj 3468 線段樹 懶標記

簡單的線段樹區間求和問題,每次改變區間值得時候採用懶標記的操作,等到下次經過這個區間的時候再將懶標記向下傳遞。include include using namespace std int n,q int a 100005 long long sum 500005 lazy 500005 void ...

字首查詢(字典樹 線段樹懶惰標記)

描述 在乙個 minecraft 村莊中,村長有這一本小寫字母構成的名冊 字串的表 每個名字旁邊都記錄著這位村民的聲望值,而且有的村民還和別人同名。隨著時間的推移,因為沒有村民死亡,這個名冊變得十分大。現在需要您來幫忙維護這個名冊,支援下列 4 種操作 1.插入新人名 si,聲望為 ai 2.給定名...