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 ...