線段樹 題解

2021-07-24 08:57:41 字數 1596 閱讀 1979

nyoj 1068

題目鏈結 

題目意思; 典型的線段樹,插線問線.不過多了乙個,

a 操作某乙個區間乙個數整體加上乙個數;

s 操作查詢某乙個區間的總和,

q 操作,查詢這個區間有多少個奇數.

下面是 線段樹延遲更新,奇數的個數更新時注意 

如果變化的是奇數,那麼  : 現在區間奇數個數=區間長度-原本區間的奇數個數.

下面 延遲更新  模板題目.如果對模板不太理解,請看這個博

或者看**注釋

延遲更新大致思想: 每一次資料更新,  [a,b] 區間,則只需要更新到他們的子區間且  滿足各個子區間無交集 且 並集為區間 [a,b];每次更新,都更新到這些子區間停止,遞迴歸的時候再更新上面的值. 查詢的時候mark,標記的是上次更新到這裡停止了,如果要往下走,標記下沉,並計算左右兒子.

#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;

typedef long long ll;

const int inf=2e9+1e8;

const int mod=1e9+7;

const int maxsize=1e6+5;

const double eps=0.0000000001;

void fre()

#define memst(a,b) memset(a,b,sizeof(a))

#define fr(i,a,n) for(int i=a;i>1ll;

if(l==r)

build(l,mid,pos<<1ll);

build(mid+1ll,r,pos<<1ll|1ll);

//上面是遞的過程,下面是歸並且求和;

tree[pos].sum=tree[pos<<1ll].sum+tree[pos<<1ll|1ll].sum;

tree[pos].odd=tree[pos<<1ll].odd+tree[pos<<1ll|1ll].odd;

return ;

}/** pushdown 函式

將本節點的左右孩子節點的標記變數加上自己節點的標記值,

且把計算結果(通常是求和)並把自己的標記值清空

*/void pushdown(ll pos)

tree[pos].mark=0;

}}/** update 函式

插線函式,遞迴開始;

如果找到子區間則,更新當前節點,因為只不需要更新到葉子節點,

所以,計算當前值,把當前節點的標記變數 加上 k,停止遞迴;

否則接著遞迴下去,每次需要下沉標記,並計算;

--> 遞迴

合併左右孩子節點的值,

*/void update(ll l,ll r,ll pos,ll k)

pushdown(pos);

if(mid>1ll;

if(tree[pos].l==l&&tree[pos].r==r)

pushdown(pos);

if(mid

題解 線段樹 關於時間

這是本蒟蒻的原創題 確實很簡單 本蒟蒻loj賬號diogenes 本題的難點在於每個操作會重複多次。核心思想是把第t秒的操作提前到第一秒,再減去多餘的部分。有一種構造方法 ad d i.j add i.j 表示區間 i j i,j 需要加的值。de l i.j del i.j 表示區間 i j i,...

線段樹練習二 題解

線段樹練習二 桌子上零散地放著若干個不同顏色的盒子,桌子的後方是一堵牆。如右圖所示。問從桌子前方可以看到多少個盒子?假設人站得足夠遠 輸入時,由底向上,從左到右 16 桌子長度 5 盒子數量 4 712 14 1 56 10 11 16 output 41 n nn 100000,1 m mm 10...

線段樹練習三 題解

線段樹練習三 給定一條長度為m mm的線段,有n nn個操作,每個操作有3個數字x xx,y yy,z zz表示把區間 x xx,y yy 染成顏色z zz,詢問染完色之後,這條長度為m mm的線段一共有幾種顏色。規定 線段的顏色可以相同。連續的相同顏色被視作一段。問x xx軸被分成多少段。inpu...