線段樹 區間合併

2021-07-16 04:40:38 字數 1558 閱讀 5402

線段樹的區間合併,即尋找

詢問區間中滿足條件的連續最長區間。

而乙個區間連續的最長區間有兩種情況:

1、此連續最長區間全在左子樹或全在右子樹,則sum[t]=max(sum[t<<1],sum[t<<1|1])

2、一部分在左子樹,一部分在右子樹,則sum[t]=suml[t<<1|1]+sum[t<<1]

因此,我們需要記錄每個區間的最長連續區間,從左邊第乙個孩子開始的最長連續區間,從右邊第乙個孩子開始的最長連續區間

附鄙人**如下:(並不能確定此**的正確性)//lenth表示每個區間的最長連續區間,right表示從左邊第乙個孩子開始的最長連續區間,left表示從右邊第乙個孩子開始的最長連續區間

#include#includeint purpose=0,ri,le,mi,total,begin,start,end,fact[200004]=,lenth[200004]=,people[200004]=,left[200004]=,right[200004]=;

int max(int a,int b)

void build(int x,int y,int n)

int m=(x+y)/2;

build(x,m,n<<1);

build(m,y,n<<1|1);

lenth[n]=max(right[n<<1]+left[n<<1|1],max(lenth[n<<1],lenth[n<<1|1]));

fact[n]=lenth[n];

left[n]=left[n<<1];

if(left[n<<1]==m-x)

right[n]=right[n<<1|1];

if(right[n<<1|1]==y-m)

printf("build:x:%d y:%d n:%d l:%d le:%d ri:%d\n",x,y,n,lenth[n],left[n],right[n]);

}void reduce(int x,int y,int n)

if(lenth[n]purpose)

}} }

else

else

else

}} lenth[n]=max(right[n<<1]+left[n<<1|1],max(lenth[n<<1],lenth[n<<1|1]));

left[n]=left[n<<1];

if(left[n<<1]==m-x)

right[n]=right[n<<1|1];

if(right[n<<1|1]==y-m)

}}void add(int x,int y,int n)

else

else

} }}

void delet(int x,int y,int n)

if(x>=begin&&y<=begin)

int m=(x+y)/2;

delet(x,m,n<<1);

delet(m,y,n<<1|1);

}int main()

else

}else

}return 0;

}

線段樹 區間合併

hdu 1540 tunnel wa re 詳細見 include include include include include define max 50010 define lson l,m,k 1 define rson m 1,r,k 1 1 using namespace std typ...

線段樹 區間合併

1 poj 3667 題意 支援兩種操作 1 如果有連續長度大於d的房間,則輸出最左的區間值,否則輸出0 2 將ql,qr區間的房間標記為 未入住 思路 節點維護三個域,該節點的最大房間數,該節點左端點起的最大房間數,該房間右端點起的最大連續房間數,用線段樹進行更新和查詢 include inclu...

線段樹區間合併

線段樹區間合併主要解決一段連續區間修改,查詢問題。線段樹是樹形結構,為解決相鄰區間更新,修改問題,我們必須在原本須要維護的區間內,連續段最大值的基礎上加上,從左,右兩邊起,最大的連續區間長度。例題 酒店 此題開始時,所有的房間都是空房間,有兩個操作 1 查詢長度為x的連續房間,並將房間全部填滿,輸出...