資料範圍很大,但是可以每行建乙個線段樹,化為線性的
set的優先順序高於add
pushdown的時候相當於在add和sett中對乙個整個的區間進行「賦值」一樣,所以還要加上改sum,min1,max1的部分
三個詢問可以一起做。。。
#include #include #include #include #include using namespace std;
#define maxn 4000000
//#define inf 1000000000
//每一行建一顆線段樹,只要開總元素個數的陣列即可,下標可以算出
int ll,rr,r,c,m,ans1,ans2,ans3,op,x1,y1,x2,y2,v;
struct pointtree[maxn];
int addv[maxn],setv[maxn];//lazy_tag
void build(int p,int l,int r)
//優先順序 set>add(當set>=0 add>0時)
void pushdown(int p)
if (addv[p]>0)
}void updata(int p)
void add(int p,int l,int r,int v)
pushdown(p);//pushdown要在這裡用,因為之前if中的已經是可以直接判斷的了
//要向下走再下傳標記
int mid=(tree[p].l+tree[p].r) >> 1;
if (r<=mid) add(p<<1,l,r,v);
if (l>mid) add(p<<1^1,l,r,v);
if (l<=mid && r>mid)
updata(p);
}void sett(int p,int l,int r,int v)
pushdown(p);
int mid=(tree[p].l+tree[p].r) >> 1;
if (r<=mid) sett(p<<1,l,r,v);
if (l>mid) sett(p<<1^1,l,r,v);
if (l<=mid && r>mid)
updata(p);
}void query(int p,int l,int r)
pushdown(p);
int mid=(tree[p].l+tree[p].r) >> 1;
if (r<=mid) query(p<<1,l,r);
if (l>mid) query(p<<1^1,l,r);
if (l<=mid && r>mid)
updata(p);
}int main()
}if (op==2)
}if (op==3)
cout<
53 線段樹區間修改(線段樹《重點》)
昨天學習了線段樹這樣一種極其重要的演算法,在競賽是具有廣泛的運用。可以用線段樹對桶等其他的演算法和結構進行維護。基本題目如下 題目描述 如題,已知乙個數列,你需要進行下面兩種操作 1.將某區間每乙個數加上x 2.求出某區間每乙個數的和 第一行包含兩個整數n m,分別表示該數列數字的個數和操作的總個數...
線段樹(2)區間修改
快速序列操作i,給出乙個n個元素的陣列a1,a2,an,你的任務是設計乙個資料結構支援一下兩種操作 set l,r,v 把al,al 1,ar的值全部修改為v v 0 query l,r 計算子串行al,al 1,ar的元素和 最小值和最大值。include include using namesp...
線段樹002 區間修改
接下來講解一下區間修改 比如在下面這個圖中我要將1 5區間的值全都改為v 正常人的思維是把1 5這個區間的修改看成對點1,2,3,4,5的單點修改 但這樣的複雜度是nlog n 是比較高的 我們換一種想法,在修改區間的時候我們仍然像區間查詢一樣自上而下的尋找要修改的區間。那麼我們最後 找到區間是1 ...