這道題自己寫了很久,還是沒寫出來,也看了很多題解,感覺多數還是看的迷迷糊糊,最後面看到一篇大佬的才感覺恍然大悟。
先說下題意:
就是給你n個數,每個數的初始值都是為0
然後給你m個操作
每個操作有 4 個數 op x y c
當 op==1 的時候,把 x到y 範圍內的數 都 加上 c
當 op==2 的時候,把 x到y 範圍內的數 都 乘以 c
當 op==3 的時候,把 x到y 範圍內的數 都 等於 c
當 op==4 的時候,把 x到y 範圍內的 每乙個數 的 c 次方的和 輸出(注意,當op等於4的時候,c的範圍為1~3)
下面說說思路:
關鍵就是在於這個 懶惰值的傳遞,和區間的每乙個值是否都相等的問題
一.先說說樹的資料
這個大家參考下就可以,實現的方法有很多,不一定需要這麼寫,把這個先放上來是便於理解。(我這麼寫是因為我太菜了)
structdata tree[m << 2];
二.再說這個區間值都相等
我們可以知道,如果區間內的每乙個值都相等,那麼我們只要 求 其中乙個的值的c次方,然後把該數乘以(右邊界 減去 左邊界 再加 1 ),便是該區間值的次方總和了
如果該區間的每乙個值不相等,那麼我們必須接著向下探索,直到 找到 乙個 區間內的每乙個值都相等 的區間,最壞的情況也就是找到葉節點。
三.懶惰值的傳遞
如果這個區間的每乙個值都相等,那麼它的左右子區間肯定也都是相等的。
如果這個區間不是全等區間,那麼我們就沒必要傳遞懶惰值,因為你這個區間每乙個值不一定相等 ; 但是如果是全等區間,就要傳遞懶惰值。
如果我們在更新資料的過程中,需要用到傳遞懶惰值,那麼肯定是要修改這個區間的某乙個子區間,所以傳遞後,這個區間肯定不會再是全等區間
四.資料的更新
我們在更新完值後,肯定也需要更新區間是否相等的資訊
有三種情況:
1.如果該區間的左右子區間 都不是 全等區間的話,那這個區間肯定也 不是 全等區間
2.如果該區間的左右子區間 都是 全等區間, 但是它們的 葉節點的值都 不相等,那麼這個區間肯定 也不是 全等區間
3.如果該區間的左右區間 都是 全等區間,並且 它們的 葉節點的值都 全等,那麼這個區間 肯定是 全等區間
下面上**:
#include #include#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define m 100005
#define mod 10007
#define inf 0x3f3f3f3f
#define left k<<1
#define right k<<1|1
#define ms(a,b) memset(a,b,sizeof(a))typedef
long
long
ll;using
namespace
std;
struct
data tree[m << 2
];ll ans, temp;
ll op, c, p;
intx, y, n, m;
void built(int l, int r, int
k) void down(int
k) void updata(int
k)
else
if (op == 2)
else
return
; }
if (tree[k].dif)down(k);//
如果該區間是全等區間,那麼就要傳遞懶惰值,並且傳遞後該區間肯定是 不全等區間
int mid = (tree[k].l + tree[k].r) >> 1
;
if (x <=mid)updata(left);
if (y >mid)updata(right);
//傳遞後三種情況分析更新
if (!tree[left].dif || !tree[right].dif)tree[k].dif = false
;
else
}}void query(int
k)
if (tree[k].dif)down(k);//
如果該區間是全等區間,那麼就要傳遞懶惰值,並且傳遞後該區間肯定是 」全等區間「
int mid = (tree[k].l + tree[k].r) >> 1
;
if (x <=mid)query(left);
if (y >mid)query(right);
}int
main()
else}}
return0;
}
HDU 4578 線段樹各種區間操作
原題鏈結 題意 初始乙個長度為n的陣列全為0,有m個操作,輸入op,l,r,x。op 1時,把 l,r 中的所有數加上x op 2時,把 l,r 中的所有樹乘上x op 3時,把 l,r 中的所有數全置為x op 4時,輸出 l,r 中所有數的 x 方的和 思路 令 x a x b 即對乙個x,令他...
hdu4578 (多標記線段樹)
對於乙個區間有4個操作 1.將a b都加上c 2.將a b都乘上c 3.將a b都變成c 4.查詢a b的每個數的p次方的和。p 1,2,3 平方和這樣來推 a c 2 a 2 2ac c 2 即 sum2 rt sum2 rt 2 sum1 rt c r l 1 c c 立方和這樣推 a c 3 ...
線段樹懶標記好題 HDU4578
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分別為一次方 二次方...