版权声明:本文为博主原创文章,未经博主允许必须转载。 https://blog.csdn.net/qq_35950004/article/details/88654763
大佬博客
这玩意我觉得是KDT的亲戚。
但是这玩意比KDT好卡多了。
主要思想就是把
的区间划分为多个
的区间且每个区间内,所有点的信息相等。
用
维护。
感觉属于熟练掌握STL的范畴。
如果数据随机而且有区间赋值操作。
期望区间数
可以实现任何暴力操作。
其实他的操作都是对区间拆拆合合,学习一下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);
}
可以出一些平常的数据结构根本没有办法做的题(比如把莫队的题强制在线)然后说一句数据随机。