729. 我的日程安排表 I(set or 动态开点线段树)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了729. 我的日程安排表 I(set or 动态开点线段树)相关的知识,希望对你有一定的参考价值。

729. 我的日程安排表 I(set or 动态开点线段树)

区间覆盖,区间查询。因此值域大,查询次数小,所以动态开点。

建树方法与普通线段树类似,就是pushdown的时候特判下左右儿子是否位空,然后所有函数都用指针即可。

时间复杂度: O ( n l o g C ) O(nlogC) O(nlogC)

class MyCalendar 
public:
    struct node
    	node *l,*r;
    	int s,lz;
    ;
	node * rt = new node();
	const int  NN = 1e9;
    MyCalendar() 
	
    
    void re(node* a)
    	a->s=a->l->s|a->r->s;
    
    void pd(node* a)
    	if(a->l==NULL) a->l= new node();
    	if(a->r==NULL) a->r= new node();
    	if(!a->lz) return;
    	a->l->s=a->lz;
    	a->r->s=a->lz;
    	a->l->lz=a->r->lz=a->lz;
    	a->lz=0;
    
    
    void upd(node *a,int l,int r,int L,int R,int v)
    	if(l>=L&&r<=R)
    		a->s=v;
    		a->lz=v;return;
    	
    	pd(a);
    	int m = l+r>>1;
    	if(L<=m) upd(a->l,l,m,L,R,v);
    	if(R>m) upd(a->r,m+1,r,L,R,v);
    	re(a);
    
    bool que(node *a,int l,int r,int L,int R)
    	if(l>=L&&r<=R) return a->s;
    	int m = l+r>>1;
    	pd(a);
    	int ok=0;
    	if(L<=m) ok|=que(a->l,l,m,L,R);
    	if(R>m) ok|=que(a->r,m+1,r,L,R);
    	return ok;
    
    bool book(int st, int ed) 
		if(que(rt,0,NN,st,ed-1)) return false;
		upd(rt,0,NN,st,ed-1,1);
		return true;
    
    
;

set,做法每次就lower_bound l>=ed的 位置 p p p

然后判断 ( − − p ) → r ≤ s t < e d ≤ l (--p)\\rightarrow r\\le st<ed\\le l (p)rst<edl

时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)

class MyCalendar 
    set<pair<int, int>> booked;

public:
    bool book(int start, int end) 
        auto it = booked.lower_bound(end, 0);
        if (it == booked.begin() || (--it)->second <= start) 
            booked.emplace(start, end);
            return true;
        
        return false;
    
;

以上是关于729. 我的日程安排表 I(set or 动态开点线段树)的主要内容,如果未能解决你的问题,请参考以下文章

每日一题729. 我的日程安排表 I

区间和与线段树

c++线段树

数据结构与算法之深入解析“我的日程安排表I”的求解思路与算法示例

leetcode731 我的日程表安排II

线段树实战最近的请求次数 + 区域和检索 - 数组可修改+我的日程安排表Ⅰ/Ⅲ