線段樹的區間合併,即尋找
詢問區間中滿足條件的連續最長區間。
而乙個區間連續的最長區間有兩種情況:
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的連續房間,並將房間全部填滿,輸出...