珂朵莉树(ODT)(玄学)

版权声明:本文为博主原创文章,未经博主允许必须转载。 https://blog.csdn.net/qq_35950004/article/details/88654763

大佬博客
这玩意我觉得是KDT的亲戚。
但是这玩意比KDT好卡多了。
主要思想就是把 [ 1 , n ] [1,n] 的区间划分为多个 [ 1 , r 1 ] , [ r 1 + 1 , r 2 ] . . . . [1,r_1],[r_1+1,r_2].... 的区间且每个区间内,所有点的信息相等。
s t d : : s e t std::set 维护。
感觉属于熟练掌握STL的范畴。
如果数据随机而且有区间赋值操作。
期望区间数 O ( lg n ) O(\lg n)
可以实现任何暴力操作。

其实他的操作都是对区间拆拆合合,学习一下STL的基本(高阶)知识就很好打了,另外对于玄学复杂度的算法,要有卡常意识。

模板题:
一个餐馆中有n个座位,这些座位排成一条直线,从左到右编号为1,2,……n。这天有m个事件发生。事件有两种:一种是有新的订单,需要p个连续的座位。如果可以满足,就找到编号最小的一组给他们坐,如果不能满足,则要拒绝这个订单;一种是区间[a,b]的人全部离开。请把餐馆的老板统计有多少个订单不能满足。

老题一般都没有卡珂朵莉树的,因此OJrank1(比OJrank2快1倍)
AC Code:

#include<bits/stdc++.h>
using namespace std;

char cb[1<<15],*cs=cb,*ct=cb;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
void read(int &res){ char ch;for(;!isdigit(ch=getc()););for(res=ch-'0';isdigit(ch=getc());res=ch-'0'+res*10); } 
struct node{
	int l,r;
	mutable int val;
	node(int l=0,int r=0,int val=0):l(l),r(r),val(val){}
	bool operator <(const node &B)const{ return l<B.l; }
};
set<node>st;
#define IT set<node>::iterator 

IT split(int pos){
	IT it = st.lower_bound(pos);
	if(it!=st.end()&&(*it).l==pos) return it;
	--it;
	int l=(*it).l,r=(*it).r,val=(*it).val;
	st.erase(it);
	st.insert(node(l,pos-1,val));
	return st.insert(node(pos,r,val)).first;
}

void assign(int l,int r,int val){
	IT itr=split(r+1),itl=split(l);
	st.erase(itl,itr);
	st.insert(node(l,r,val));
}

int n,m;

int main(){
	read(n),read(m);
	st.insert(node(1,n,0));
	int u,v,ans=0;
	for(char s[3];m--;){
		for(;!isalpha(s[0]=getc()););
		if(s[0] == 'L'){
			read(u),read(v);
			assign(u,v,0);
		}
		else{
			read(u);
			bool flag = 0;
			for(IT it=st.begin(),it2;it!=st.end();)
			{
				if((*it).val==0){
					if((*it).r-(*it).l+1>=u){
						flag=1;
						int l = (*it).l , r = (*it).r;
						st.erase(it);
						st.insert(node(l,l+u-1,1));
						st.insert(node(l+u,r,0));
						break;
					}
				}
				it2=it;
				it2++;
				if(it2!=st.end() && (*it).val==(*it2).val){
					int l = (*it).l , r = (*it2).r,val=(*it).val;
					st.erase(it),st.erase(it2);
					it=st.insert(node(l,r,val)).first;
				}
				else it=it2;
			}
			if(!flag) ans++;
		}
	}
	printf("%d\n",ans);
}

可以出一些平常的数据结构根本没有办法做的题(比如把莫队的题强制在线)然后说一句数据随机。

猜你喜欢

转载自blog.csdn.net/qq_35950004/article/details/88654763