为了获取实验数据,研究员想要知道在区间[l, r]上有多少种不同大小的机器人。
形式化地说,对于一个长度为n的初始全1序列,之后会有多次三种操作:
珂朵莉树模板题 ,以前cf遇到过好像还没存过板子。
基本模型就是 数据随机 存在区间整体推平操作(就是把一段区间的值变成一样) 可以使得期望的存在区间很少 就可以暴力的进行区间遍历。 其余时候是把 区间当作一个单位按顺序存在set里,注意区间都是断开的,也就是 线段上每个点都只存在一个区间里,但是相邻的区间就算权值相同也不一定合在一起,就是存在两个相邻区间但是值也相同的情况,所以不能简单认为一个区间内的数字个数就是 set里面这段范围内区间的个数,实际上权值个数是小于等于区间个数的。
#include
using namespace std;
#define maxn 1000005
#define maxm 1006
#define ll long long int
#define INF 0x3f3f3f3f
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,r,l) for(int i=r;i>=l;i--)
#define mem(a) memset(a,0,sizeof(a))
#define sqr(x) (x*x)
#define inf (ll)2e18+1
#define PI acos(-1)
#define mod 1000000007
#define auto(i,x) for(int i=head[x];i;i=ed[i].nxt)
#define IT set::iterator
ll read(){
ll x=0,f=1ll;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return f*x;
}
int n,m;
struct node{
int l,r;
mutable ll v;
node(){};
node(int L, int R=-1, ll V=0):l(L), r(R), v(V) {}
bool operator<(const node& o) const
{
return l < o.l;
}
};
set<node>s;
IT split(int pos)
{
IT it = s.lower_bound(node(pos));
if (it != s.end() && it->l == pos)
return it;
--it;
int L = it->l, R = it->r;
ll V = it->v;
s.erase(it);
s.insert(node(L, pos-1, V));
return s.insert(node(pos, R, V)).first;
}
void add(int l, int r, ll val)
{
IT itr = split(r+1),itl = split(l);
for (; itl != itr; ++itl)
{ itl->v=val; }
}
void assign_val(int l, int r, ll val)
{
IT itr = split(r+1),itl = split(l);
s.erase(itl, itr);
s.insert(node(l, r, val));
}
ll sum(int l, int r)
{
IT itr = split(r+1),itl = split(l);
ll res = 0;
for (; itl != itr; ++itl)
res = res + (ll)(itl->r - itl->l + 1) * itl->v ;
return res;
}
int cont(int l,int r){
IT itr = split(r+1),itl = split(l);
vector<ll>v;
for (; itl != itr; ++itl)
v.push_back(itl->v);
sort(v.begin(),v.end());
int len=unique(v.begin(),v.end())-v.begin();
if(v[0]==0)len--;
return len;
}
int main()
{
n=read();m=read();
s.insert(node(1,n,1));
int op,x,y;
inc(i,1,m){
op=read();x=read();y=read();
if(op==1){
assign_val(x,y,1);
}
else if(op==2){
ll res=sum(x,y);
assign_val(x,y-1,0);
assign_val(y,y,res);
}
else printf("%d\n",cont(x,y));
}
return 0;
}
/*
1000 11
3 1 200
2 633 635
3 1 200
1 656 789
2 688 953
3 95 661
3 398 602
1 653 769
1 364 440
2 205 422
2 186 981
*/