poj3667 線段樹區間操作

2021-08-18 16:50:46 字數 1359 閱讀 4980

poj3667

題意給出n,m(1<=n,m<=50000),表示乙個有n個空位的數列,對其進行m次操作

給出兩種操作:

1 di:表示將數列中最左端的連續di個空位填滿,輸出被填滿區間左端點的位置,若無法做到則不填並輸出0

2 xi di:將區間[xi,xi+di-1]清空

題目分析

建一棵線段樹,每個節點維護該區間內最大左/右連續空位和最大連續空位和標記f,f==1表示該區間被填滿,f==-1表示該區間被清空。利用標記f對線段樹進行區間操作。

**(ac)

#include#include#includeusing namespace std;

const int n=55000;

int n,m;

struct node

};node *root;

inline void pushdown(node *p)

inline void update(node *p)

pushdown(p->lt); pushdown(p->rt);

if (p->lt->n==p->lt->r-p->lt->l+1) p->ln=p->lt->n+p->rt->ln;

else p->ln=p->lt->ln;

if (p->rt->n==p->rt->r-p->rt->l+1) p->rn=p->rt->n+p->lt->rn;

else p->rn=p->rt->rn;

p->n=max(p->lt->rn+p->rt->ln,max(p->lt->n,p->rt->n));

}void build(node *&p,int l,int r)

update(p);

}void print(node *p)

int find(node *p,int dis)

void ins(node *p,int u,int v)

int mid=(p->l+p->r)>>1;

if (u<=mid) ins(p->lt,u,v);

if (mid+1<=v) ins(p->rt,u,v);

update(p);

}void del(node *p,int u,int v)

int mid=(p->l+p->r)>>1;

if (u<=mid) del(p->lt,u,v);

if (mid+1<=v) del(p->rt,u,v);

update(p);

} int main()

if (type==2)

//print(root);

} return 0;

}

poj3667 線段樹(區間合併)

題意 有編號為1 n的n個房間,有兩種詢問 1.有人來訂連續的k間房,有的話返回第一間房的編號,否則返回0。2.有人退連續的從a開始的連續的k間房。1.該區間最大的連續空房數 2.該區間從最左邊起的最大的連續空房數 3.該區間從最右邊起的最大的連續空房數 根據以上三個資訊,每個非葉結點的資訊都可以由...

poj 3667 線段樹 區間合併

感想 沒有什麼說的了。越做線段樹越感覺自己水。這個我感覺自己就真坑了大家了。難的不會,簡單的也水不過了。哎,最近這是什麼情況啊!題目 題意 旅館有編號為1 n的房間,現在可能有m波人過了租房,每波人可能要定連續的d間房,如果有的話,編號盡量小,沒有的話就說0,也可能有d個人要退房,他們的房是連續的x...

線段樹區間合併poj3667

題意 1 a表示如果有長度為a的連續的空房間,則占用 2 a b表示清空 a,a b 1 的房間 思路 線段樹區間維護,除了考慮區間上最大空房間,還要維護左邊最大連續和右邊最大連續 include include include include using namespace std define ...