tyuan 这次原味喝多少 lazytag
tre 这次热带风味喝多少 lazytag
yuan 最多连续喝了多少原味
re 最多连续喝了多少热带风味
myuan 最少连续喝了多少原味
mre 最少连续喝了多少热带风味
tag 击毁 lazytag
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll read(){
ll k=0,flag=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-')flag=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
k=(k<<1)+(k<<3)+(c^48);
c=getchar();
}
return k*flag;
}
void print(ll x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)print(x/10);
putchar(x%10+'0');
return ;
}
const int N=2e5+10;
int n,q;
struct node{
int l,r;
ll sum,yuan,re,tyuan,tre,myuan,mre;
bool tag;
}tr[N<<2];
void build(int i,int l,int r){
tr[i].l=l;
tr[i].r=r;
tr[i].tyuan=tr[i].tre=1e18;//标记赋值
if(l==r){
tr[i].sum=1;//初始化个数
return ;
}
int mid=l+r>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
tr[i].sum=tr[i<<1].sum+tr[i<<1|1].sum;
return ;
}
void pushup(int i){
tr[i].sum=tr[i<<1].sum+tr[i<<1|1].sum;
tr[i].re=max(tr[i<<1].re,tr[i<<1|1].re);
tr[i].mre=min(tr[i<<1].mre,tr[i<<1|1].mre);
tr[i].yuan=max(tr[i<<1].yuan,tr[i<<1|1].yuan);
tr[i].myuan=min(tr[i<<1].myuan,tr[i<<1|1].myuan);
return ;
}
void pushdown(int i){
if(tr[i].tag){//击毁了,所有变量清空
tr[i<<1].tag=tr[i<<1|1].tag=1;
tr[i<<1].sum=tr[i<<1|1].sum=0;
tr[i<<1].myuan=tr[i<<1|1].myuan=0;
tr[i<<1].yuan=tr[i<<1|1].yuan=0;
tr[i<<1].mre=tr[i<<1|1].mre=0;
tr[i<<1].re=tr[i<<1|1].re=0;
tr[i<<1].tre=tr[i<<1|1].tre=1e18;
tr[i<<1].tyuan=tr[i<<1|1].tyuan=1e18;
tr[i].tag=0;
}
if(tr[i].tyuan!=1e18){//喝的原味,清空热带风味的变量,并处理原味的变量
if(tr[i<<1].tyuan==1e18)tr[i<<1].tyuan=tr[i].tyuan;
else tr[i<<1].tyuan+=tr[i].tyuan;
if(tr[i<<1|1].tyuan==1e18)tr[i<<1|1].tyuan=tr[i].tyuan;
else tr[i<<1|1].tyuan+=tr[i].tyuan;
tr[i<<1].tre=tr[i<<1|1].tre=1e18;
tr[i<<1].mre=tr[i<<1|1].mre=0;
tr[i<<1].re=tr[i<<1|1].re=0;
tr[i<<1].yuan+=tr[i].tyuan;
tr[i<<1|1].yuan+=tr[i].tyuan;
tr[i<<1].myuan+=tr[i].tyuan;
tr[i<<1|1].myuan+=tr[i].tyuan;
tr[i].tyuan=1e18;
}
if(tr[i].tre!=1e18){//喝的热带风味,与上面处理方式相反
if(tr[i<<1].tre==1e18)tr[i<<1].tre=tr[i].tre;
else tr[i<<1].tre+=tr[i].tre;
if(tr[i<<1|1].tre==1e18)tr[i<<1|1].tre=tr[i].tre;
else tr[i<<1|1].tre+=tr[i].tre;
tr[i<<1].tyuan=tr[i<<1|1].tyuan=1e18;
tr[i<<1].myuan=tr[i<<1|1].myuan=0;
tr[i<<1].yuan=tr[i<<1|1].yuan=0;
tr[i<<1].re+=tr[i].tre;
tr[i<<1|1].re+=tr[i].tre;
tr[i<<1].mre+=tr[i].tre;
tr[i<<1|1].mre+=tr[i].tre;
tr[i].tre=1e18;
}
return ;
}
void adyuan(int i,int l,int r,ll k){//和原味
if(!tr[i].sum)return ;
if(l<=tr[i].l&&tr[i].r<=r){
tr[i].yuan+=k;
tr[i].myuan+=k;
if(tr[i].tyuan==1e18)tr[i].tyuan=k;
else tr[i].tyuan+=k;
tr[i].tre=1e18;
tr[i].mre=tr[i].re=0;
return ;
}
pushdown(i);
int mid=tr[i].l+tr[i].r>>1;
if(l<=mid)adyuan(i<<1,l,r,k);
if(mid<r)adyuan(i<<1|1,l,r,k);
pushup(i);
return ;
}
void adre(int i,int l,int r,ll k){//喝热带风味
if(!tr[i].sum)return ;
if(l<=tr[i].l&&tr[i].r<=r){
tr[i].re+=k;
tr[i].mre+=k;
if(tr[i].tre==1e18)tr[i].tre=k;
else tr[i].tre+=k;
tr[i].tyuan=1e18;
tr[i].myuan=tr[i].yuan=0;
return ;
}
pushdown(i);
int mid=tr[i].l+tr[i].r>>1;
if(l<=mid)adre(i<<1,l,r,k);
if(mid<r)adre(i<<1|1,l,r,k);
pushup(i);
return ;
}
void del(int i,int l,int r,ll k){
if(!tr[i].sum||tr[i].re<k&&tr[i].yuan<k)return ;//如果这一区间没有要删的就 return
if(l<=tr[i].l&&tr[i].r<=r){
if(tr[i].mre>=k||tr[i].myuan>=k){//符合要求就删除
tr[i].yuan=tr[i].re=tr[i].mre=tr[i].myuan=tr[i].sum=0;
tr[i].tyuan=tr[i].tre=1e18;
tr[i].tag=1;
return ;
}
if(tr[i].l==tr[i].r)return ;
pushdown(i);//先 pushdown 一遍
del(i<<1,l,r,k);//区间不全符合要求,那么向左右分别递归
del(i<<1|1,l,r,k);
}
pushdown(i);
int mid=tr[i].l+tr[i].r>>1;
if(l<=mid)del(i<<1,l,r,k);
if(mid<r)del(i<<1|1,l,r,k);
pushup(i);
return ;
}
int main(){
cin>>n>>q;
build(1,1,n);
while(q--){
int op=read();
if(op==1){
int l=read(),r=read();
ll k=read();
adyuan(1,l,r,k);
if(l>1)adre(1,1,l-1,k);
if(r<n)adre(1,r+1,n,k);
}
if(op==2){
int l=read(),r=read();
ll k=read();
del(1,l,r,k);
}
if(op==3){
print(tr[1].sum);
puts("");
}
}
return 0;
}